1 /* 2 * Copyright (C) 2016-2018 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 <algorithm> 20 #include <chrono> 21 #include <mutex> 22 #include <regex> 23 #include <unordered_map> 24 #include <unordered_set> 25 #include <condition_variable> 26 27 #include <inttypes.h> 28 29 #include <android/hardware/camera/device/1.0/ICameraDevice.h> 30 #include <android/hardware/camera/device/3.2/ICameraDevice.h> 31 #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h> 32 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h> 33 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h> 34 #include <android/hardware/camera/provider/2.4/ICameraProvider.h> 35 #include <android/hidl/manager/1.0/IServiceManager.h> 36 #include <binder/MemoryHeapBase.h> 37 #include <CameraMetadata.h> 38 #include <CameraParameters.h> 39 #include <cutils/properties.h> 40 #include <fmq/MessageQueue.h> 41 #include <grallocusage/GrallocUsageConversion.h> 42 #include <gui/BufferItemConsumer.h> 43 #include <gui/BufferQueue.h> 44 #include <gui/Surface.h> 45 #include <hardware/gralloc.h> 46 #include <hardware/gralloc1.h> 47 #include <system/camera.h> 48 #include <system/camera_metadata.h> 49 #include <ui/GraphicBuffer.h> 50 51 #include <android/hardware/graphics/allocator/2.0/IAllocator.h> 52 #include <android/hardware/graphics/mapper/2.0/IMapper.h> 53 #include <android/hardware/graphics/mapper/2.0/types.h> 54 #include <android/hidl/allocator/1.0/IAllocator.h> 55 #include <android/hidl/memory/1.0/IMapper.h> 56 #include <android/hidl/memory/1.0/IMemory.h> 57 58 #include <VtsHalHidlTargetTestBase.h> 59 #include <VtsHalHidlTargetTestEnvBase.h> 60 61 using namespace ::android::hardware::camera::device; 62 using ::android::hardware::Return; 63 using ::android::hardware::Void; 64 using ::android::hardware::hidl_handle; 65 using ::android::hardware::hidl_string; 66 using ::android::hardware::hidl_vec; 67 using ::android::sp; 68 using ::android::wp; 69 using ::android::GraphicBuffer; 70 using ::android::IGraphicBufferProducer; 71 using ::android::IGraphicBufferConsumer; 72 using ::android::BufferQueue; 73 using ::android::BufferItemConsumer; 74 using ::android::Surface; 75 using ::android::hardware::graphics::common::V1_0::BufferUsage; 76 using ::android::hardware::graphics::common::V1_0::Dataspace; 77 using ::android::hardware::graphics::common::V1_0::PixelFormat; 78 using ::android::hardware::camera::common::V1_0::Status; 79 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus; 80 using ::android::hardware::camera::common::V1_0::TorchMode; 81 using ::android::hardware::camera::common::V1_0::TorchModeStatus; 82 using ::android::hardware::camera::common::V1_0::helper::CameraParameters; 83 using ::android::hardware::camera::common::V1_0::helper::Size; 84 using ::android::hardware::camera::provider::V2_4::ICameraProvider; 85 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; 86 using ::android::hardware::camera::device::V3_2::ICameraDevice; 87 using ::android::hardware::camera::device::V3_2::BufferCache; 88 using ::android::hardware::camera::device::V3_2::CaptureRequest; 89 using ::android::hardware::camera::device::V3_2::CaptureResult; 90 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback; 91 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession; 92 using ::android::hardware::camera::device::V3_2::NotifyMsg; 93 using ::android::hardware::camera::device::V3_2::RequestTemplate; 94 using ::android::hardware::camera::device::V3_2::StreamType; 95 using ::android::hardware::camera::device::V3_2::StreamRotation; 96 using ::android::hardware::camera::device::V3_2::StreamConfiguration; 97 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode; 98 using ::android::hardware::camera::device::V3_2::CameraMetadata; 99 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration; 100 using ::android::hardware::camera::device::V3_2::BufferStatus; 101 using ::android::hardware::camera::device::V3_2::StreamBuffer; 102 using ::android::hardware::camera::device::V3_2::MsgType; 103 using ::android::hardware::camera::device::V3_2::ErrorMsg; 104 using ::android::hardware::camera::device::V3_2::ErrorCode; 105 using ::android::hardware::camera::device::V1_0::CameraFacing; 106 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg; 107 using ::android::hardware::camera::device::V1_0::CommandType; 108 using ::android::hardware::camera::device::V1_0::DataCallbackMsg; 109 using ::android::hardware::camera::device::V1_0::CameraFrameMetadata; 110 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback; 111 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag; 112 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage; 113 using ::android::hardware::MessageQueue; 114 using ::android::hardware::kSynchronizedReadWrite; 115 using ::android::hidl::allocator::V1_0::IAllocator; 116 using ::android::hidl::memory::V1_0::IMemory; 117 using ::android::hidl::memory::V1_0::IMapper; 118 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; 119 using ::android::hidl::manager::V1_0::IServiceManager; 120 121 using namespace ::android::hardware::camera; 122 123 const uint32_t kMaxPreviewWidth = 1920; 124 const uint32_t kMaxPreviewHeight = 1080; 125 const uint32_t kMaxVideoWidth = 4096; 126 const uint32_t kMaxVideoHeight = 2160; 127 const int64_t kStreamBufferTimeoutSec = 3; 128 const int64_t kAutoFocusTimeoutSec = 5; 129 const int64_t kTorchTimeoutSec = 1; 130 const int64_t kEmptyFlushTimeoutMSec = 200; 131 const char kDumpOutput[] = "/dev/null"; 132 const uint32_t kBurstFrameCount = 10; 133 134 struct AvailableStream { 135 int32_t width; 136 int32_t height; 137 int32_t format; 138 }; 139 140 struct AvailableZSLInputOutput { 141 int32_t inputFormat; 142 int32_t outputFormat; 143 }; 144 145 namespace { 146 // "device@<version>/legacy/<id>" 147 const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)"; 148 const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304; 149 const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303; 150 const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302; 151 const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100; 152 const char *kHAL3_4 = "3.4"; 153 const char *kHAL3_3 = "3.3"; 154 const char *kHAL3_2 = "3.2"; 155 const char *kHAL1_0 = "1.0"; 156 157 bool matchDeviceName(const hidl_string& deviceName, 158 const hidl_string &providerType, 159 std::string* deviceVersion, 160 std::string* cameraId) { 161 ::android::String8 pattern; 162 pattern.appendFormat(kDeviceNameRE, providerType.c_str()); 163 std::regex e(pattern.string()); 164 std::string deviceNameStd(deviceName.c_str()); 165 std::smatch sm; 166 if (std::regex_match(deviceNameStd, sm, e)) { 167 if (deviceVersion != nullptr) { 168 *deviceVersion = sm[1]; 169 } 170 if (cameraId != nullptr) { 171 *cameraId = sm[2]; 172 } 173 return true; 174 } 175 return false; 176 } 177 178 int getCameraDeviceVersion(const hidl_string& deviceName, 179 const hidl_string &providerType) { 180 std::string version; 181 bool match = matchDeviceName(deviceName, providerType, &version, nullptr); 182 if (!match) { 183 return -1; 184 } 185 186 if (version.compare(kHAL3_4) == 0) { 187 return CAMERA_DEVICE_API_VERSION_3_4; 188 } else if (version.compare(kHAL3_3) == 0) { 189 return CAMERA_DEVICE_API_VERSION_3_3; 190 } else if (version.compare(kHAL3_2) == 0) { 191 return CAMERA_DEVICE_API_VERSION_3_2; 192 } else if (version.compare(kHAL1_0) == 0) { 193 return CAMERA_DEVICE_API_VERSION_1_0; 194 } 195 return 0; 196 } 197 198 bool parseProviderName(const std::string& name, std::string *type /*out*/, 199 uint32_t *id /*out*/) { 200 if (!type || !id) { 201 ADD_FAILURE(); 202 return false; 203 } 204 205 std::string::size_type slashIdx = name.find('/'); 206 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) { 207 ADD_FAILURE() << "Provider name does not have / separator between type" 208 "and id"; 209 return false; 210 } 211 212 std::string typeVal = name.substr(0, slashIdx); 213 214 char *endPtr; 215 errno = 0; 216 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10); 217 if (errno != 0) { 218 ADD_FAILURE() << "cannot parse provider id as an integer:" << 219 name.c_str() << strerror(errno) << errno; 220 return false; 221 } 222 if (endPtr != name.c_str() + name.size()) { 223 ADD_FAILURE() << "provider id has unexpected length " << name.c_str(); 224 return false; 225 } 226 if (idVal < 0) { 227 ADD_FAILURE() << "id is negative: " << name.c_str() << idVal; 228 return false; 229 } 230 231 *type = typeVal; 232 *id = static_cast<uint32_t>(idVal); 233 234 return true; 235 } 236 237 Status mapToStatus(::android::status_t s) { 238 switch(s) { 239 case ::android::OK: 240 return Status::OK ; 241 case ::android::BAD_VALUE: 242 return Status::ILLEGAL_ARGUMENT ; 243 case -EBUSY: 244 return Status::CAMERA_IN_USE; 245 case -EUSERS: 246 return Status::MAX_CAMERAS_IN_USE; 247 case ::android::UNKNOWN_TRANSACTION: 248 return Status::METHOD_NOT_SUPPORTED; 249 case ::android::INVALID_OPERATION: 250 return Status::OPERATION_NOT_SUPPORTED; 251 case ::android::DEAD_OBJECT: 252 return Status::CAMERA_DISCONNECTED; 253 } 254 ALOGW("Unexpected HAL status code %d", s); 255 return Status::OPERATION_NOT_SUPPORTED; 256 } 257 } 258 259 // Test environment for camera 260 class CameraHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { 261 public: 262 // get the test environment singleton 263 static CameraHidlEnvironment* Instance() { 264 static CameraHidlEnvironment* instance = new CameraHidlEnvironment; 265 return instance; 266 } 267 268 virtual void HidlSetUp() override { ALOGI("SetUp CameraHidlEnvironment"); } 269 270 virtual void HidlTearDown() override { ALOGI("TearDown CameraHidlEnvironment"); } 271 272 virtual void registerTestServices() override { registerTestService<ICameraProvider>(); } 273 274 private: 275 CameraHidlEnvironment() {} 276 277 GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment); 278 }; 279 280 struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener { 281 BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {} 282 283 void onFrameAvailable(const android::BufferItem&) override { 284 sp<BufferItemConsumer> consumer = mConsumer.promote(); 285 ASSERT_NE(nullptr, consumer.get()); 286 287 android::BufferItem buffer; 288 ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0)); 289 ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer)); 290 } 291 292 private: 293 wp<BufferItemConsumer> mConsumer; 294 }; 295 296 struct PreviewWindowCb : public ICameraDevicePreviewCallback { 297 PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0), 298 mPreviewHeight(0), mFormat(0), mPreviewUsage(0), 299 mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {} 300 301 using dequeueBuffer_cb = 302 std::function<void(Status status, uint64_t bufferId, 303 const hidl_handle& buffer, uint32_t stride)>; 304 Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override; 305 306 Return<Status> enqueueBuffer(uint64_t bufferId) override; 307 308 Return<Status> cancelBuffer(uint64_t bufferId) override; 309 310 Return<Status> setBufferCount(uint32_t count) override; 311 312 Return<Status> setBuffersGeometry(uint32_t w, 313 uint32_t h, PixelFormat format) override; 314 315 Return<Status> setCrop(int32_t left, int32_t top, 316 int32_t right, int32_t bottom) override; 317 318 Return<Status> setUsage(BufferUsage usage) override; 319 320 Return<Status> setSwapInterval(int32_t interval) override; 321 322 using getMinUndequeuedBufferCount_cb = 323 std::function<void(Status status, uint32_t count)>; 324 Return<void> getMinUndequeuedBufferCount( 325 getMinUndequeuedBufferCount_cb _hidl_cb) override; 326 327 Return<Status> setTimestamp(int64_t timestamp) override; 328 329 private: 330 struct BufferHasher { 331 size_t operator()(const buffer_handle_t& buf) const { 332 if (buf == nullptr) 333 return 0; 334 335 size_t result = 1; 336 result = 31 * result + buf->numFds; 337 for (int i = 0; i < buf->numFds; i++) { 338 result = 31 * result + buf->data[i]; 339 } 340 return result; 341 } 342 }; 343 344 struct BufferComparator { 345 bool operator()(const buffer_handle_t& buf1, 346 const buffer_handle_t& buf2) const { 347 if (buf1->numFds == buf2->numFds) { 348 for (int i = 0; i < buf1->numFds; i++) { 349 if (buf1->data[i] != buf2->data[i]) { 350 return false; 351 } 352 } 353 return true; 354 } 355 return false; 356 } 357 }; 358 359 std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb); 360 void cleanupCirculatingBuffers(); 361 362 std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId 363 typedef std::unordered_map<const buffer_handle_t, uint64_t, 364 BufferHasher, BufferComparator> BufferIdMap; 365 366 BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map 367 std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap; 368 uint64_t mNextBufferId = 1; 369 370 uint32_t mPreviewWidth, mPreviewHeight; 371 int mFormat, mPreviewUsage; 372 int32_t mPreviewSwapInterval; 373 android_native_rect_t mCrop; 374 sp<ANativeWindow> mAnw; //Native window reference 375 }; 376 377 std::pair<bool, uint64_t> PreviewWindowCb::getBufferId( 378 ANativeWindowBuffer* anb) { 379 std::lock_guard<std::mutex> lock(mBufferIdMapLock); 380 381 buffer_handle_t& buf = anb->handle; 382 auto it = mBufferIdMap.find(buf); 383 if (it == mBufferIdMap.end()) { 384 uint64_t bufId = mNextBufferId++; 385 mBufferIdMap[buf] = bufId; 386 mReversedBufMap[bufId] = anb; 387 return std::make_pair(true, bufId); 388 } else { 389 return std::make_pair(false, it->second); 390 } 391 } 392 393 void PreviewWindowCb::cleanupCirculatingBuffers() { 394 std::lock_guard<std::mutex> lock(mBufferIdMapLock); 395 mBufferIdMap.clear(); 396 mReversedBufMap.clear(); 397 } 398 399 Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) { 400 ANativeWindowBuffer* anb; 401 auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb); 402 uint64_t bufferId = 0; 403 uint32_t stride = 0; 404 hidl_handle buf = nullptr; 405 if (rc == ::android::OK) { 406 auto pair = getBufferId(anb); 407 buf = (pair.first) ? anb->handle : nullptr; 408 bufferId = pair.second; 409 stride = anb->stride; 410 } 411 412 _hidl_cb(mapToStatus(rc), bufferId, buf, stride); 413 return Void(); 414 } 415 416 Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) { 417 if (mReversedBufMap.count(bufferId) == 0) { 418 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId); 419 return Status::ILLEGAL_ARGUMENT; 420 } 421 return mapToStatus(mAnw->queueBuffer(mAnw.get(), 422 mReversedBufMap.at(bufferId), -1)); 423 } 424 425 Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) { 426 if (mReversedBufMap.count(bufferId) == 0) { 427 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId); 428 return Status::ILLEGAL_ARGUMENT; 429 } 430 return mapToStatus(mAnw->cancelBuffer(mAnw.get(), 431 mReversedBufMap.at(bufferId), -1)); 432 } 433 434 Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) { 435 if (mAnw.get() != nullptr) { 436 // WAR for b/27039775 437 native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); 438 native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA); 439 if (mPreviewWidth != 0) { 440 native_window_set_buffers_dimensions(mAnw.get(), 441 mPreviewWidth, mPreviewHeight); 442 native_window_set_buffers_format(mAnw.get(), mFormat); 443 } 444 if (mPreviewUsage != 0) { 445 native_window_set_usage(mAnw.get(), mPreviewUsage); 446 } 447 if (mPreviewSwapInterval >= 0) { 448 mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval); 449 } 450 if (mCrop.left >= 0) { 451 native_window_set_crop(mAnw.get(), &(mCrop)); 452 } 453 } 454 455 auto rc = native_window_set_buffer_count(mAnw.get(), count); 456 if (rc == ::android::OK) { 457 cleanupCirculatingBuffers(); 458 } 459 460 return mapToStatus(rc); 461 } 462 463 Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h, 464 PixelFormat format) { 465 auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h); 466 if (rc == ::android::OK) { 467 mPreviewWidth = w; 468 mPreviewHeight = h; 469 rc = native_window_set_buffers_format(mAnw.get(), 470 static_cast<int>(format)); 471 if (rc == ::android::OK) { 472 mFormat = static_cast<int>(format); 473 } 474 } 475 476 return mapToStatus(rc); 477 } 478 479 Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top, 480 int32_t right, int32_t bottom) { 481 android_native_rect_t crop = { left, top, right, bottom }; 482 auto rc = native_window_set_crop(mAnw.get(), &crop); 483 if (rc == ::android::OK) { 484 mCrop = crop; 485 } 486 return mapToStatus(rc); 487 } 488 489 Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) { 490 auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage)); 491 if (rc == ::android::OK) { 492 mPreviewUsage = static_cast<int>(usage); 493 } 494 return mapToStatus(rc); 495 } 496 497 Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) { 498 auto rc = mAnw->setSwapInterval(mAnw.get(), interval); 499 if (rc == ::android::OK) { 500 mPreviewSwapInterval = interval; 501 } 502 return mapToStatus(rc); 503 } 504 505 Return<void> PreviewWindowCb::getMinUndequeuedBufferCount( 506 getMinUndequeuedBufferCount_cb _hidl_cb) { 507 int count = 0; 508 auto rc = mAnw->query(mAnw.get(), 509 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count); 510 _hidl_cb(mapToStatus(rc), count); 511 return Void(); 512 } 513 514 Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) { 515 return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(), 516 timestamp)); 517 } 518 519 // The main test class for camera HIDL HAL. 520 class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase { 521 public: 522 virtual void SetUp() override { 523 string service_name = CameraHidlEnvironment::Instance()->getServiceName<ICameraProvider>(); 524 ALOGI("get service with name: %s", service_name.c_str()); 525 mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(service_name); 526 ASSERT_NE(mProvider, nullptr); 527 528 uint32_t id; 529 ASSERT_TRUE(parseProviderName(service_name, &mProviderType, &id)); 530 } 531 virtual void TearDown() override {} 532 533 hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider); 534 535 struct EmptyDeviceCb : public ICameraDeviceCallback { 536 virtual Return<void> processCaptureResult( 537 const hidl_vec<CaptureResult>& /*results*/) override { 538 ALOGI("processCaptureResult callback"); 539 ADD_FAILURE(); // Empty callback should not reach here 540 return Void(); 541 } 542 543 virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override { 544 ALOGI("notify callback"); 545 ADD_FAILURE(); // Empty callback should not reach here 546 return Void(); 547 } 548 }; 549 550 struct DeviceCb : public V3_4::ICameraDeviceCallback { 551 DeviceCb(CameraHidlTest *parent) : mParent(parent) {} 552 Return<void> processCaptureResult_3_4( 553 const hidl_vec<V3_4::CaptureResult>& results) override; 554 Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override; 555 Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override; 556 557 private: 558 bool processCaptureResultLocked(const CaptureResult& results); 559 560 CameraHidlTest *mParent; // Parent object 561 }; 562 563 struct TorchProviderCb : public ICameraProviderCallback { 564 TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {} 565 virtual Return<void> cameraDeviceStatusChange( 566 const hidl_string&, CameraDeviceStatus) override { 567 return Void(); 568 } 569 570 virtual Return<void> torchModeStatusChange( 571 const hidl_string&, TorchModeStatus newStatus) override { 572 std::lock_guard<std::mutex> l(mParent->mTorchLock); 573 mParent->mTorchStatus = newStatus; 574 mParent->mTorchCond.notify_one(); 575 return Void(); 576 } 577 578 private: 579 CameraHidlTest *mParent; // Parent object 580 }; 581 582 struct Camera1DeviceCb : 583 public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback { 584 Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {} 585 586 Return<void> notifyCallback(NotifyCallbackMsg msgType, 587 int32_t ext1, int32_t ext2) override; 588 589 Return<uint32_t> registerMemory(const hidl_handle& descriptor, 590 uint32_t bufferSize, uint32_t bufferCount) override; 591 592 Return<void> unregisterMemory(uint32_t memId) override; 593 594 Return<void> dataCallback(DataCallbackMsg msgType, 595 uint32_t data, uint32_t bufferIndex, 596 const CameraFrameMetadata& metadata) override; 597 598 Return<void> dataCallbackTimestamp(DataCallbackMsg msgType, 599 uint32_t data, uint32_t bufferIndex, 600 int64_t timestamp) override; 601 602 Return<void> handleCallbackTimestamp(DataCallbackMsg msgType, 603 const hidl_handle& frameData,uint32_t data, 604 uint32_t bufferIndex, int64_t timestamp) override; 605 606 Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType, 607 const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override; 608 609 610 private: 611 CameraHidlTest *mParent; // Parent object 612 }; 613 614 void openCameraDevice(const std::string &name, sp<ICameraProvider> provider, 615 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/); 616 void setupPreviewWindow( 617 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 618 sp<BufferItemConsumer> *bufferItemConsumer /*out*/, 619 sp<BufferItemHander> *bufferHandler /*out*/); 620 void stopPreviewAndClose( 621 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 622 void startPreview( 623 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 624 void enableMsgType(unsigned int msgType, 625 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 626 void disableMsgType(unsigned int msgType, 627 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device); 628 void getParameters( 629 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 630 CameraParameters *cameraParams /*out*/); 631 void setParameters( 632 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 633 const CameraParameters &cameraParams); 634 void allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage, 635 PixelFormat format, hidl_handle *buffer_handle /*out*/); 636 void waitForFrameLocked(DataCallbackMsg msgFrame, 637 std::unique_lock<std::mutex> &l); 638 void openEmptyDeviceSession(const std::string &name, 639 sp<ICameraProvider> provider, 640 sp<ICameraDeviceSession> *session /*out*/, 641 camera_metadata_t **staticMeta /*out*/); 642 void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion, 643 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, 644 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/); 645 void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2, 646 StreamConfigurationMode configMode, 647 ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, 648 ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4); 649 650 void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, 651 sp<ICameraProvider> provider, 652 const AvailableStream *previewThreshold, 653 const std::unordered_set<std::string>& physicalIds, 654 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, 655 V3_2::Stream* previewStream /*out*/, 656 device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, 657 bool *supportsPartialResults /*out*/, 658 uint32_t *partialResultCount /*out*/); 659 void configurePreviewStream(const std::string &name, int32_t deviceVersion, 660 sp<ICameraProvider> provider, 661 const AvailableStream *previewThreshold, 662 sp<ICameraDeviceSession> *session /*out*/, 663 V3_2::Stream *previewStream /*out*/, 664 HalStreamConfiguration *halStreamConfig /*out*/, 665 bool *supportsPartialResults /*out*/, 666 uint32_t *partialResultCount /*out*/); 667 static Status getAvailableOutputStreams(camera_metadata_t *staticMeta, 668 std::vector<AvailableStream> &outputStreams, 669 const AvailableStream *threshold = nullptr); 670 static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta); 671 static Status isLogicalMultiCamera(camera_metadata_t *staticMeta); 672 static Status getPhysicalCameraIds(camera_metadata_t *staticMeta, 673 std::unordered_set<std::string> *physicalIds/*out*/); 674 static Status getSupportedKeys(camera_metadata_t *staticMeta, 675 uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/); 676 static void constructFilteredSettings(const sp<ICameraDeviceSession>& session, 677 const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate, 678 android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/, 679 android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings 680 /*out*/); 681 static Status pickConstrainedModeSize(camera_metadata_t *staticMeta, 682 AvailableStream &hfrStream); 683 static Status isZSLModeAvailable(camera_metadata_t *staticMeta); 684 static Status getZSLInputOutputMap(camera_metadata_t *staticMeta, 685 std::vector<AvailableZSLInputOutput> &inputOutputMap); 686 static Status findLargestSize( 687 const std::vector<AvailableStream> &streamSizes, 688 int32_t format, AvailableStream &result); 689 static Status isAutoFocusModeAvailable( 690 CameraParameters &cameraParams, const char *mode) ; 691 692 protected: 693 694 // In-flight queue for tracking completion of capture requests. 695 struct InFlightRequest { 696 // Set by notify() SHUTTER call. 697 nsecs_t shutterTimestamp; 698 699 bool errorCodeValid; 700 ErrorCode errorCode; 701 702 //Is partial result supported 703 bool usePartialResult; 704 705 //Partial result count expected 706 uint32_t numPartialResults; 707 708 // Message queue 709 std::shared_ptr<ResultMetadataQueue> resultQueue; 710 711 // Set by process_capture_result call with valid metadata 712 bool haveResultMetadata; 713 714 // Decremented by calls to process_capture_result with valid output 715 // and input buffers 716 ssize_t numBuffersLeft; 717 718 // A 64bit integer to index the frame number associated with this result. 719 int64_t frameNumber; 720 721 // The partial result count (index) for this capture result. 722 int32_t partialResultCount; 723 724 // For buffer drop errors, the stream ID for the stream that lost a buffer. 725 // Otherwise -1. 726 int32_t errorStreamId; 727 728 // If this request has any input buffer 729 bool hasInputBuffer; 730 731 // Result metadata 732 ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult; 733 734 // Buffers are added by process_capture_result when output buffers 735 // return from HAL but framework. 736 ::android::Vector<StreamBuffer> resultOutputBuffers; 737 738 InFlightRequest() : 739 shutterTimestamp(0), 740 errorCodeValid(false), 741 errorCode(ErrorCode::ERROR_BUFFER), 742 usePartialResult(false), 743 numPartialResults(0), 744 resultQueue(nullptr), 745 haveResultMetadata(false), 746 numBuffersLeft(0), 747 frameNumber(0), 748 partialResultCount(0), 749 errorStreamId(-1), 750 hasInputBuffer(false) {} 751 752 InFlightRequest(ssize_t numBuffers, bool hasInput, 753 bool partialResults, uint32_t partialCount, 754 std::shared_ptr<ResultMetadataQueue> queue = nullptr) : 755 shutterTimestamp(0), 756 errorCodeValid(false), 757 errorCode(ErrorCode::ERROR_BUFFER), 758 usePartialResult(partialResults), 759 numPartialResults(partialCount), 760 resultQueue(queue), 761 haveResultMetadata(false), 762 numBuffersLeft(numBuffers), 763 frameNumber(0), 764 partialResultCount(0), 765 errorStreamId(-1), 766 hasInputBuffer(hasInput) {} 767 }; 768 769 // Map from frame number to the in-flight request state 770 typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap; 771 772 std::mutex mLock; // Synchronize access to member variables 773 std::condition_variable mResultCondition; // Condition variable for incoming results 774 InFlightMap mInflightMap; // Map of all inflight requests 775 776 DataCallbackMsg mDataMessageTypeReceived; // Most recent message type received through data callbacks 777 uint32_t mVideoBufferIndex; // Buffer index of the most recent video buffer 778 uint32_t mVideoData; // Buffer data of the most recent video buffer 779 hidl_handle mVideoNativeHandle; // Most recent video buffer native handle 780 NotifyCallbackMsg mNotifyMessage; // Current notification message 781 782 std::mutex mTorchLock; // Synchronize access to torch status 783 std::condition_variable mTorchCond; // Condition variable for torch status 784 TorchModeStatus mTorchStatus; // Current torch status 785 786 // Holds camera registered buffers 787 std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool; 788 789 // Camera provider service 790 sp<ICameraProvider> mProvider; 791 // Camera provider type. 792 std::string mProviderType; 793 }; 794 795 Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback( 796 NotifyCallbackMsg msgType, int32_t ext1 __unused, 797 int32_t ext2 __unused) { 798 std::unique_lock<std::mutex> l(mParent->mLock); 799 mParent->mNotifyMessage = msgType; 800 mParent->mResultCondition.notify_one(); 801 802 return Void(); 803 } 804 805 Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory( 806 const hidl_handle& descriptor, uint32_t bufferSize, 807 uint32_t bufferCount) { 808 if (descriptor->numFds != 1) { 809 ADD_FAILURE() << "camera memory descriptor has" 810 " numFds " << descriptor->numFds << " (expect 1)" ; 811 return 0; 812 } 813 if (descriptor->data[0] < 0) { 814 ADD_FAILURE() << "camera memory descriptor has" 815 " FD " << descriptor->data[0] << " (expect >= 0)"; 816 return 0; 817 } 818 819 sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase( 820 descriptor->data[0], bufferSize*bufferCount, 0, 0); 821 mParent->mMemoryPool.emplace(pool->getHeapID(), pool); 822 823 return pool->getHeapID(); 824 } 825 826 Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) { 827 if (mParent->mMemoryPool.count(memId) == 0) { 828 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId); 829 ADD_FAILURE(); 830 return Void(); 831 } 832 833 mParent->mMemoryPool.erase(memId); 834 return Void(); 835 } 836 837 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback( 838 DataCallbackMsg msgType __unused, uint32_t data __unused, 839 uint32_t bufferIndex __unused, 840 const CameraFrameMetadata& metadata __unused) { 841 std::unique_lock<std::mutex> l(mParent->mLock); 842 mParent->mDataMessageTypeReceived = msgType; 843 mParent->mResultCondition.notify_one(); 844 845 return Void(); 846 } 847 848 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp( 849 DataCallbackMsg msgType, uint32_t data, 850 uint32_t bufferIndex, int64_t timestamp __unused) { 851 std::unique_lock<std::mutex> l(mParent->mLock); 852 mParent->mDataMessageTypeReceived = msgType; 853 mParent->mVideoBufferIndex = bufferIndex; 854 if (mParent->mMemoryPool.count(data) == 0) { 855 ADD_FAILURE() << "memory pool ID " << data << "not found"; 856 } 857 mParent->mVideoData = data; 858 mParent->mResultCondition.notify_one(); 859 860 return Void(); 861 } 862 863 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp( 864 DataCallbackMsg msgType, const hidl_handle& frameData, 865 uint32_t data __unused, uint32_t bufferIndex, 866 int64_t timestamp __unused) { 867 std::unique_lock<std::mutex> l(mParent->mLock); 868 mParent->mDataMessageTypeReceived = msgType; 869 mParent->mVideoBufferIndex = bufferIndex; 870 if (mParent->mMemoryPool.count(data) == 0) { 871 ADD_FAILURE() << "memory pool ID " << data << " not found"; 872 } 873 mParent->mVideoData = data; 874 mParent->mVideoNativeHandle = frameData; 875 mParent->mResultCondition.notify_one(); 876 877 return Void(); 878 } 879 880 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch( 881 DataCallbackMsg msgType, 882 const hidl_vec<HandleTimestampMessage>& batch) { 883 std::unique_lock<std::mutex> l(mParent->mLock); 884 for (auto& msg : batch) { 885 mParent->mDataMessageTypeReceived = msgType; 886 mParent->mVideoBufferIndex = msg.bufferIndex; 887 if (mParent->mMemoryPool.count(msg.data) == 0) { 888 ADD_FAILURE() << "memory pool ID " << msg.data << " not found"; 889 } 890 mParent->mVideoData = msg.data; 891 mParent->mVideoNativeHandle = msg.frameData; 892 mParent->mResultCondition.notify_one(); 893 } 894 return Void(); 895 } 896 897 Return<void> CameraHidlTest::DeviceCb::processCaptureResult_3_4( 898 const hidl_vec<V3_4::CaptureResult>& results) { 899 900 if (nullptr == mParent) { 901 return Void(); 902 } 903 904 bool notify = false; 905 std::unique_lock<std::mutex> l(mParent->mLock); 906 for (size_t i = 0 ; i < results.size(); i++) { 907 notify = processCaptureResultLocked(results[i].v3_2); 908 } 909 910 l.unlock(); 911 if (notify) { 912 mParent->mResultCondition.notify_one(); 913 } 914 915 return Void(); 916 } 917 918 Return<void> CameraHidlTest::DeviceCb::processCaptureResult( 919 const hidl_vec<CaptureResult>& results) { 920 if (nullptr == mParent) { 921 return Void(); 922 } 923 924 bool notify = false; 925 std::unique_lock<std::mutex> l(mParent->mLock); 926 for (size_t i = 0 ; i < results.size(); i++) { 927 notify = processCaptureResultLocked(results[i]); 928 } 929 930 l.unlock(); 931 if (notify) { 932 mParent->mResultCondition.notify_one(); 933 } 934 935 return Void(); 936 } 937 938 bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& results) { 939 bool notify = false; 940 uint32_t frameNumber = results.frameNumber; 941 942 if ((results.result.size() == 0) && 943 (results.outputBuffers.size() == 0) && 944 (results.inputBuffer.buffer == nullptr) && 945 (results.fmqResultSize == 0)) { 946 ALOGE("%s: No result data provided by HAL for frame %d result count: %d", 947 __func__, frameNumber, (int) results.fmqResultSize); 948 ADD_FAILURE(); 949 return notify; 950 } 951 952 ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber); 953 if (::android::NAME_NOT_FOUND == idx) { 954 ALOGE("%s: Unexpected frame number! received: %u", 955 __func__, frameNumber); 956 ADD_FAILURE(); 957 return notify; 958 } 959 960 bool isPartialResult = false; 961 bool hasInputBufferInRequest = false; 962 InFlightRequest *request = mParent->mInflightMap.editValueAt(idx); 963 ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata; 964 size_t resultSize = 0; 965 if (results.fmqResultSize > 0) { 966 resultMetadata.resize(results.fmqResultSize); 967 if (request->resultQueue == nullptr) { 968 ADD_FAILURE(); 969 return notify; 970 } 971 if (!request->resultQueue->read(resultMetadata.data(), 972 results.fmqResultSize)) { 973 ALOGE("%s: Frame %d: Cannot read camera metadata from fmq," 974 "size = %" PRIu64, __func__, frameNumber, 975 results.fmqResultSize); 976 ADD_FAILURE(); 977 return notify; 978 } 979 resultSize = resultMetadata.size(); 980 } else if (results.result.size() > 0) { 981 resultMetadata.setToExternal(const_cast<uint8_t *>( 982 results.result.data()), results.result.size()); 983 resultSize = resultMetadata.size(); 984 } 985 986 if (!request->usePartialResult && (resultSize > 0) && 987 (results.partialResult != 1)) { 988 ALOGE("%s: Result is malformed for frame %d: partial_result %u " 989 "must be 1 if partial result is not supported", __func__, 990 frameNumber, results.partialResult); 991 ADD_FAILURE(); 992 return notify; 993 } 994 995 if (results.partialResult != 0) { 996 request->partialResultCount = results.partialResult; 997 } 998 999 // Check if this result carries only partial metadata 1000 if (request->usePartialResult && (resultSize > 0)) { 1001 if ((results.partialResult > request->numPartialResults) || 1002 (results.partialResult < 1)) { 1003 ALOGE("%s: Result is malformed for frame %d: partial_result %u" 1004 " must be in the range of [1, %d] when metadata is " 1005 "included in the result", __func__, frameNumber, 1006 results.partialResult, request->numPartialResults); 1007 ADD_FAILURE(); 1008 return notify; 1009 } 1010 request->collectedResult.append( 1011 reinterpret_cast<const camera_metadata_t*>( 1012 resultMetadata.data())); 1013 1014 isPartialResult = 1015 (results.partialResult < request->numPartialResults); 1016 } else if (resultSize > 0) { 1017 request->collectedResult.append(reinterpret_cast<const camera_metadata_t*>( 1018 resultMetadata.data())); 1019 isPartialResult = false; 1020 } 1021 1022 hasInputBufferInRequest = request->hasInputBuffer; 1023 1024 // Did we get the (final) result metadata for this capture? 1025 if ((resultSize > 0) && !isPartialResult) { 1026 if (request->haveResultMetadata) { 1027 ALOGE("%s: Called multiple times with metadata for frame %d", 1028 __func__, frameNumber); 1029 ADD_FAILURE(); 1030 return notify; 1031 } 1032 request->haveResultMetadata = true; 1033 request->collectedResult.sort(); 1034 } 1035 1036 uint32_t numBuffersReturned = results.outputBuffers.size(); 1037 if (results.inputBuffer.buffer != nullptr) { 1038 if (hasInputBufferInRequest) { 1039 numBuffersReturned += 1; 1040 } else { 1041 ALOGW("%s: Input buffer should be NULL if there is no input" 1042 " buffer sent in the request", __func__); 1043 } 1044 } 1045 request->numBuffersLeft -= numBuffersReturned; 1046 if (request->numBuffersLeft < 0) { 1047 ALOGE("%s: Too many buffers returned for frame %d", __func__, 1048 frameNumber); 1049 ADD_FAILURE(); 1050 return notify; 1051 } 1052 1053 request->resultOutputBuffers.appendArray(results.outputBuffers.data(), 1054 results.outputBuffers.size()); 1055 // If shutter event is received notify the pending threads. 1056 if (request->shutterTimestamp != 0) { 1057 notify = true; 1058 } 1059 return notify; 1060 } 1061 1062 Return<void> CameraHidlTest::DeviceCb::notify( 1063 const hidl_vec<NotifyMsg>& messages) { 1064 std::lock_guard<std::mutex> l(mParent->mLock); 1065 1066 for (size_t i = 0; i < messages.size(); i++) { 1067 ssize_t idx = mParent->mInflightMap.indexOfKey( 1068 messages[i].msg.shutter.frameNumber); 1069 if (::android::NAME_NOT_FOUND == idx) { 1070 ALOGE("%s: Unexpected frame number! received: %u", 1071 __func__, messages[i].msg.shutter.frameNumber); 1072 ADD_FAILURE(); 1073 break; 1074 } 1075 InFlightRequest *r = mParent->mInflightMap.editValueAt(idx); 1076 1077 switch(messages[i].type) { 1078 case MsgType::ERROR: 1079 if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) { 1080 ALOGE("%s: Camera reported serious device error", 1081 __func__); 1082 ADD_FAILURE(); 1083 } else { 1084 r->errorCodeValid = true; 1085 r->errorCode = messages[i].msg.error.errorCode; 1086 r->errorStreamId = messages[i].msg.error.errorStreamId; 1087 } 1088 break; 1089 case MsgType::SHUTTER: 1090 r->shutterTimestamp = messages[i].msg.shutter.timestamp; 1091 break; 1092 default: 1093 ALOGE("%s: Unsupported notify message %d", __func__, 1094 messages[i].type); 1095 ADD_FAILURE(); 1096 break; 1097 } 1098 } 1099 1100 mParent->mResultCondition.notify_one(); 1101 return Void(); 1102 } 1103 1104 hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) { 1105 std::vector<std::string> cameraDeviceNames; 1106 Return<void> ret; 1107 ret = provider->getCameraIdList( 1108 [&](auto status, const auto& idList) { 1109 ALOGI("getCameraIdList returns status:%d", (int)status); 1110 for (size_t i = 0; i < idList.size(); i++) { 1111 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str()); 1112 } 1113 ASSERT_EQ(Status::OK, status); 1114 for (const auto& id : idList) { 1115 cameraDeviceNames.push_back(id); 1116 } 1117 }); 1118 if (!ret.isOk()) { 1119 ADD_FAILURE(); 1120 } 1121 1122 // External camera devices are reported through cameraDeviceStatusChange 1123 struct ProviderCb : public ICameraProviderCallback { 1124 virtual Return<void> cameraDeviceStatusChange( 1125 const hidl_string& devName, 1126 CameraDeviceStatus newStatus) override { 1127 ALOGI("camera device status callback name %s, status %d", 1128 devName.c_str(), (int) newStatus); 1129 if (newStatus == CameraDeviceStatus::PRESENT) { 1130 externalCameraDeviceNames.push_back(devName); 1131 1132 } 1133 return Void(); 1134 } 1135 1136 virtual Return<void> torchModeStatusChange( 1137 const hidl_string&, TorchModeStatus) override { 1138 return Void(); 1139 } 1140 1141 std::vector<std::string> externalCameraDeviceNames; 1142 }; 1143 sp<ProviderCb> cb = new ProviderCb; 1144 auto status = mProvider->setCallback(cb); 1145 1146 for (const auto& devName : cb->externalCameraDeviceNames) { 1147 if (cameraDeviceNames.end() == std::find( 1148 cameraDeviceNames.begin(), cameraDeviceNames.end(), devName)) { 1149 cameraDeviceNames.push_back(devName); 1150 } 1151 } 1152 1153 hidl_vec<hidl_string> retList(cameraDeviceNames.size()); 1154 for (size_t i = 0; i < cameraDeviceNames.size(); i++) { 1155 retList[i] = cameraDeviceNames[i]; 1156 } 1157 return retList; 1158 } 1159 1160 // Test devices with first_api_level >= P does not advertise device (at) 1.0 1161 TEST_F(CameraHidlTest, noHal1AfterP) { 1162 constexpr int32_t HAL1_PHASE_OUT_API_LEVEL = 28; 1163 int32_t firstApiLevel = property_get_int32("ro.product.first_api_level", /*default*/-1); 1164 if (firstApiLevel < 0) { 1165 firstApiLevel = property_get_int32("ro.build.version.sdk", /*default*/-1); 1166 } 1167 ASSERT_GT(firstApiLevel, 0); // first_api_level must exist 1168 1169 if (firstApiLevel >= HAL1_PHASE_OUT_API_LEVEL) { 1170 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1171 for (const auto& name : cameraDeviceNames) { 1172 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 1173 ASSERT_NE(deviceVersion, 0); // Must be a valid device version 1174 ASSERT_NE(deviceVersion, CAMERA_DEVICE_API_VERSION_1_0); // Must not be device (at) 1.0 1175 } 1176 } 1177 } 1178 1179 // Test if ICameraProvider::isTorchModeSupported returns Status::OK 1180 TEST_F(CameraHidlTest, isTorchModeSupported) { 1181 Return<void> ret; 1182 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) { 1183 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support); 1184 ASSERT_EQ(Status::OK, status); 1185 }); 1186 ASSERT_TRUE(ret.isOk()); 1187 } 1188 1189 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage 1190 TEST_F(CameraHidlTest, getCameraIdList) { 1191 Return<void> ret; 1192 ret = mProvider->getCameraIdList([&](auto status, const auto& idList) { 1193 ALOGI("getCameraIdList returns status:%d", (int)status); 1194 for (size_t i = 0; i < idList.size(); i++) { 1195 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str()); 1196 } 1197 ASSERT_EQ(Status::OK, status); 1198 }); 1199 ASSERT_TRUE(ret.isOk()); 1200 } 1201 1202 // Test if ICameraProvider::getVendorTags returns Status::OK 1203 TEST_F(CameraHidlTest, getVendorTags) { 1204 Return<void> ret; 1205 ret = mProvider->getVendorTags([&](auto status, const auto& vendorTagSecs) { 1206 ALOGI("getVendorTags returns status:%d numSections %zu", (int)status, vendorTagSecs.size()); 1207 for (size_t i = 0; i < vendorTagSecs.size(); i++) { 1208 ALOGI("Vendor tag section %zu name %s", i, vendorTagSecs[i].sectionName.c_str()); 1209 for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) { 1210 const auto& tag = vendorTagSecs[i].tags[j]; 1211 ALOGI("Vendor tag id %u name %s type %d", tag.tagId, tag.tagName.c_str(), 1212 (int)tag.tagType); 1213 } 1214 } 1215 ASSERT_EQ(Status::OK, status); 1216 }); 1217 ASSERT_TRUE(ret.isOk()); 1218 } 1219 1220 // Test if ICameraProvider::setCallback returns Status::OK 1221 TEST_F(CameraHidlTest, setCallback) { 1222 struct ProviderCb : public ICameraProviderCallback { 1223 virtual Return<void> cameraDeviceStatusChange( 1224 const hidl_string& cameraDeviceName, 1225 CameraDeviceStatus newStatus) override { 1226 ALOGI("camera device status callback name %s, status %d", 1227 cameraDeviceName.c_str(), (int) newStatus); 1228 return Void(); 1229 } 1230 1231 virtual Return<void> torchModeStatusChange( 1232 const hidl_string& cameraDeviceName, 1233 TorchModeStatus newStatus) override { 1234 ALOGI("Torch mode status callback name %s, status %d", 1235 cameraDeviceName.c_str(), (int) newStatus); 1236 return Void(); 1237 } 1238 }; 1239 sp<ProviderCb> cb = new ProviderCb; 1240 auto status = mProvider->setCallback(cb); 1241 ASSERT_TRUE(status.isOk()); 1242 ASSERT_EQ(Status::OK, status); 1243 status = mProvider->setCallback(nullptr); 1244 ASSERT_TRUE(status.isOk()); 1245 ASSERT_EQ(Status::OK, status); 1246 } 1247 1248 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device 1249 TEST_F(CameraHidlTest, getCameraDeviceInterface) { 1250 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1251 1252 for (const auto& name : cameraDeviceNames) { 1253 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 1254 switch (deviceVersion) { 1255 case CAMERA_DEVICE_API_VERSION_3_4: 1256 case CAMERA_DEVICE_API_VERSION_3_3: 1257 case CAMERA_DEVICE_API_VERSION_3_2: { 1258 Return<void> ret; 1259 ret = mProvider->getCameraDeviceInterface_V3_x( 1260 name, [&](auto status, const auto& device3_x) { 1261 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 1262 ASSERT_EQ(Status::OK, status); 1263 ASSERT_NE(device3_x, nullptr); 1264 }); 1265 ASSERT_TRUE(ret.isOk()); 1266 } 1267 break; 1268 case CAMERA_DEVICE_API_VERSION_1_0: { 1269 Return<void> ret; 1270 ret = mProvider->getCameraDeviceInterface_V1_x( 1271 name, [&](auto status, const auto& device1) { 1272 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 1273 ASSERT_EQ(Status::OK, status); 1274 ASSERT_NE(device1, nullptr); 1275 }); 1276 ASSERT_TRUE(ret.isOk()); 1277 } 1278 break; 1279 default: { 1280 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 1281 ADD_FAILURE(); 1282 } 1283 break; 1284 } 1285 } 1286 } 1287 1288 // Verify that the device resource cost can be retrieved and the values are 1289 // sane. 1290 TEST_F(CameraHidlTest, getResourceCost) { 1291 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1292 1293 for (const auto& name : cameraDeviceNames) { 1294 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 1295 switch (deviceVersion) { 1296 case CAMERA_DEVICE_API_VERSION_3_4: 1297 case CAMERA_DEVICE_API_VERSION_3_3: 1298 case CAMERA_DEVICE_API_VERSION_3_2: { 1299 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 1300 ALOGI("getResourceCost: Testing camera device %s", name.c_str()); 1301 Return<void> ret; 1302 ret = mProvider->getCameraDeviceInterface_V3_x( 1303 name, [&](auto status, const auto& device) { 1304 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 1305 ASSERT_EQ(Status::OK, status); 1306 ASSERT_NE(device, nullptr); 1307 device3_x = device; 1308 }); 1309 ASSERT_TRUE(ret.isOk()); 1310 1311 ret = device3_x->getResourceCost([&](auto status, const auto& resourceCost) { 1312 ALOGI("getResourceCost returns status:%d", (int)status); 1313 ASSERT_EQ(Status::OK, status); 1314 ALOGI(" Resource cost is %d", resourceCost.resourceCost); 1315 ASSERT_LE(resourceCost.resourceCost, 100u); 1316 for (const auto& name : resourceCost.conflictingDevices) { 1317 ALOGI(" Conflicting device: %s", name.c_str()); 1318 } 1319 }); 1320 ASSERT_TRUE(ret.isOk()); 1321 } 1322 break; 1323 case CAMERA_DEVICE_API_VERSION_1_0: { 1324 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1325 ALOGI("getResourceCost: Testing camera device %s", name.c_str()); 1326 Return<void> ret; 1327 ret = mProvider->getCameraDeviceInterface_V1_x( 1328 name, [&](auto status, const auto& device) { 1329 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 1330 ASSERT_EQ(Status::OK, status); 1331 ASSERT_NE(device, nullptr); 1332 device1 = device; 1333 }); 1334 ASSERT_TRUE(ret.isOk()); 1335 1336 ret = device1->getResourceCost([&](auto status, const auto& resourceCost) { 1337 ALOGI("getResourceCost returns status:%d", (int)status); 1338 ASSERT_EQ(Status::OK, status); 1339 ALOGI(" Resource cost is %d", resourceCost.resourceCost); 1340 ASSERT_LE(resourceCost.resourceCost, 100u); 1341 for (const auto& name : resourceCost.conflictingDevices) { 1342 ALOGI(" Conflicting device: %s", name.c_str()); 1343 } 1344 }); 1345 ASSERT_TRUE(ret.isOk()); 1346 } 1347 break; 1348 default: { 1349 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 1350 ADD_FAILURE(); 1351 } 1352 break; 1353 } 1354 } 1355 } 1356 1357 // Verify that the static camera info can be retrieved 1358 // successfully. 1359 TEST_F(CameraHidlTest, getCameraInfo) { 1360 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1361 1362 for (const auto& name : cameraDeviceNames) { 1363 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1364 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1365 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str()); 1366 Return<void> ret; 1367 ret = mProvider->getCameraDeviceInterface_V1_x( 1368 name, [&](auto status, const auto& device) { 1369 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 1370 ASSERT_EQ(Status::OK, status); 1371 ASSERT_NE(device, nullptr); 1372 device1 = device; 1373 }); 1374 ASSERT_TRUE(ret.isOk()); 1375 1376 ret = device1->getCameraInfo([&](auto status, const auto& info) { 1377 ALOGI("getCameraInfo returns status:%d", (int)status); 1378 ASSERT_EQ(Status::OK, status); 1379 switch (info.orientation) { 1380 case 0: 1381 case 90: 1382 case 180: 1383 case 270: 1384 // Expected cases 1385 ALOGI("camera orientation: %d", info.orientation); 1386 break; 1387 default: 1388 FAIL() << "Unexpected camera orientation:" << info.orientation; 1389 } 1390 switch (info.facing) { 1391 case CameraFacing::BACK: 1392 case CameraFacing::FRONT: 1393 case CameraFacing::EXTERNAL: 1394 // Expected cases 1395 ALOGI("camera facing: %d", info.facing); 1396 break; 1397 default: 1398 FAIL() << "Unexpected camera facing:" << static_cast<uint32_t>(info.facing); 1399 } 1400 }); 1401 ASSERT_TRUE(ret.isOk()); 1402 } 1403 } 1404 } 1405 1406 // Check whether preview window can be configured 1407 TEST_F(CameraHidlTest, setPreviewWindow) { 1408 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1409 1410 for (const auto& name : cameraDeviceNames) { 1411 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1412 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1413 openCameraDevice(name, mProvider, &device1 /*out*/); 1414 ASSERT_NE(nullptr, device1.get()); 1415 sp<BufferItemConsumer> bufferItemConsumer; 1416 sp<BufferItemHander> bufferHandler; 1417 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1418 1419 Return<void> ret; 1420 ret = device1->close(); 1421 ASSERT_TRUE(ret.isOk()); 1422 } 1423 } 1424 } 1425 1426 // Verify that setting preview window fails in case device is not open 1427 TEST_F(CameraHidlTest, setPreviewWindowInvalid) { 1428 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1429 1430 for (const auto& name : cameraDeviceNames) { 1431 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1432 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1433 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str()); 1434 Return<void> ret; 1435 ret = mProvider->getCameraDeviceInterface_V1_x( 1436 name, [&](auto status, const auto& device) { 1437 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 1438 ASSERT_EQ(Status::OK, status); 1439 ASSERT_NE(device, nullptr); 1440 device1 = device; 1441 }); 1442 ASSERT_TRUE(ret.isOk()); 1443 1444 Return<Status> returnStatus = device1->setPreviewWindow(nullptr); 1445 ASSERT_TRUE(returnStatus.isOk()); 1446 ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus); 1447 } 1448 } 1449 } 1450 1451 // Start and stop preview checking whether it gets enabled in between. 1452 TEST_F(CameraHidlTest, startStopPreview) { 1453 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1454 1455 for (const auto& name : cameraDeviceNames) { 1456 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1457 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1458 openCameraDevice(name, mProvider, &device1 /*out*/); 1459 ASSERT_NE(nullptr, device1.get()); 1460 sp<BufferItemConsumer> bufferItemConsumer; 1461 sp<BufferItemHander> bufferHandler; 1462 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1463 1464 startPreview(device1); 1465 1466 Return<bool> returnBoolStatus = device1->previewEnabled(); 1467 ASSERT_TRUE(returnBoolStatus.isOk()); 1468 ASSERT_TRUE(returnBoolStatus); 1469 1470 stopPreviewAndClose(device1); 1471 } 1472 } 1473 } 1474 1475 // Start preview without active preview window. Preview should start as soon 1476 // as a valid active window gets configured. 1477 TEST_F(CameraHidlTest, startStopPreviewDelayed) { 1478 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1479 1480 for (const auto& name : cameraDeviceNames) { 1481 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1482 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1483 openCameraDevice(name, mProvider, &device1 /*out*/); 1484 ASSERT_NE(nullptr, device1.get()); 1485 1486 Return<Status> returnStatus = device1->setPreviewWindow(nullptr); 1487 ASSERT_TRUE(returnStatus.isOk()); 1488 ASSERT_EQ(Status::OK, returnStatus); 1489 1490 startPreview(device1); 1491 1492 sp<BufferItemConsumer> bufferItemConsumer; 1493 sp<BufferItemHander> bufferHandler; 1494 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1495 1496 // Preview should get enabled now 1497 Return<bool> returnBoolStatus = device1->previewEnabled(); 1498 ASSERT_TRUE(returnBoolStatus.isOk()); 1499 ASSERT_TRUE(returnBoolStatus); 1500 1501 stopPreviewAndClose(device1); 1502 } 1503 } 1504 } 1505 1506 // Verify that image capture behaves as expected along with preview callbacks. 1507 TEST_F(CameraHidlTest, takePicture) { 1508 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1509 1510 for (const auto& name : cameraDeviceNames) { 1511 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1512 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1513 openCameraDevice(name, mProvider, &device1 /*out*/); 1514 ASSERT_NE(nullptr, device1.get()); 1515 sp<BufferItemConsumer> bufferItemConsumer; 1516 sp<BufferItemHander> bufferHandler; 1517 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1518 1519 { 1520 std::unique_lock<std::mutex> l(mLock); 1521 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1522 } 1523 1524 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1); 1525 startPreview(device1); 1526 1527 { 1528 std::unique_lock<std::mutex> l(mLock); 1529 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l); 1530 } 1531 1532 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1); 1533 enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1); 1534 1535 { 1536 std::unique_lock<std::mutex> l(mLock); 1537 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1538 } 1539 1540 Return<Status> returnStatus = device1->takePicture(); 1541 ASSERT_TRUE(returnStatus.isOk()); 1542 ASSERT_EQ(Status::OK, returnStatus); 1543 1544 { 1545 std::unique_lock<std::mutex> l(mLock); 1546 waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l); 1547 } 1548 1549 disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1); 1550 stopPreviewAndClose(device1); 1551 } 1552 } 1553 } 1554 1555 // Image capture should fail in case preview didn't get enabled first. 1556 TEST_F(CameraHidlTest, takePictureFail) { 1557 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1558 1559 for (const auto& name : cameraDeviceNames) { 1560 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1561 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1562 openCameraDevice(name, mProvider, &device1 /*out*/); 1563 ASSERT_NE(nullptr, device1.get()); 1564 1565 Return<Status> returnStatus = device1->takePicture(); 1566 ASSERT_TRUE(returnStatus.isOk()); 1567 ASSERT_NE(Status::OK, returnStatus); 1568 1569 Return<void> ret = device1->close(); 1570 ASSERT_TRUE(ret.isOk()); 1571 } 1572 } 1573 } 1574 1575 // Verify that image capture can be cancelled. 1576 TEST_F(CameraHidlTest, cancelPicture) { 1577 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1578 1579 for (const auto& name : cameraDeviceNames) { 1580 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1581 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1582 openCameraDevice(name, mProvider, &device1 /*out*/); 1583 ASSERT_NE(nullptr, device1.get()); 1584 sp<BufferItemConsumer> bufferItemConsumer; 1585 sp<BufferItemHander> bufferHandler; 1586 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1587 startPreview(device1); 1588 1589 Return<Status> returnStatus = device1->takePicture(); 1590 ASSERT_TRUE(returnStatus.isOk()); 1591 ASSERT_EQ(Status::OK, returnStatus); 1592 1593 returnStatus = device1->cancelPicture(); 1594 ASSERT_TRUE(returnStatus.isOk()); 1595 ASSERT_EQ(Status::OK, returnStatus); 1596 1597 stopPreviewAndClose(device1); 1598 } 1599 } 1600 } 1601 1602 // Image capture cancel is a no-op when image capture is not running. 1603 TEST_F(CameraHidlTest, cancelPictureNOP) { 1604 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1605 1606 for (const auto& name : cameraDeviceNames) { 1607 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1608 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1609 openCameraDevice(name, mProvider, &device1 /*out*/); 1610 ASSERT_NE(nullptr, device1.get()); 1611 sp<BufferItemConsumer> bufferItemConsumer; 1612 sp<BufferItemHander> bufferHandler; 1613 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1614 startPreview(device1); 1615 1616 Return<Status> returnStatus = device1->cancelPicture(); 1617 ASSERT_TRUE(returnStatus.isOk()); 1618 ASSERT_EQ(Status::OK, returnStatus); 1619 1620 stopPreviewAndClose(device1); 1621 } 1622 } 1623 } 1624 1625 // Test basic video recording. 1626 TEST_F(CameraHidlTest, startStopRecording) { 1627 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1628 1629 for (const auto& name : cameraDeviceNames) { 1630 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1631 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1632 openCameraDevice(name, mProvider, &device1 /*out*/); 1633 ASSERT_NE(nullptr, device1.get()); 1634 sp<BufferItemConsumer> bufferItemConsumer; 1635 sp<BufferItemHander> bufferHandler; 1636 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1637 1638 { 1639 std::unique_lock<std::mutex> l(mLock); 1640 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1641 } 1642 1643 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1); 1644 startPreview(device1); 1645 1646 { 1647 std::unique_lock<std::mutex> l(mLock); 1648 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l); 1649 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY; 1650 mVideoBufferIndex = UINT32_MAX; 1651 } 1652 1653 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1); 1654 1655 bool videoMetaEnabled = false; 1656 Return<Status> returnStatus = device1->storeMetaDataInBuffers(true); 1657 ASSERT_TRUE(returnStatus.isOk()); 1658 // It is allowed for devices to not support this feature 1659 ASSERT_TRUE((Status::OK == returnStatus) || 1660 (Status::OPERATION_NOT_SUPPORTED == returnStatus)); 1661 if (Status::OK == returnStatus) { 1662 videoMetaEnabled = true; 1663 } 1664 1665 enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1); 1666 Return<bool> returnBoolStatus = device1->recordingEnabled(); 1667 ASSERT_TRUE(returnBoolStatus.isOk()); 1668 ASSERT_FALSE(returnBoolStatus); 1669 1670 returnStatus = device1->startRecording(); 1671 ASSERT_TRUE(returnStatus.isOk()); 1672 ASSERT_EQ(Status::OK, returnStatus); 1673 1674 { 1675 std::unique_lock<std::mutex> l(mLock); 1676 waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l); 1677 ASSERT_NE(UINT32_MAX, mVideoBufferIndex); 1678 disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1); 1679 } 1680 1681 returnBoolStatus = device1->recordingEnabled(); 1682 ASSERT_TRUE(returnBoolStatus.isOk()); 1683 ASSERT_TRUE(returnBoolStatus); 1684 1685 Return<void> ret; 1686 if (videoMetaEnabled) { 1687 ret = device1->releaseRecordingFrameHandle(mVideoData, mVideoBufferIndex, 1688 mVideoNativeHandle); 1689 ASSERT_TRUE(ret.isOk()); 1690 } else { 1691 ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex); 1692 ASSERT_TRUE(ret.isOk()); 1693 } 1694 1695 ret = device1->stopRecording(); 1696 ASSERT_TRUE(ret.isOk()); 1697 1698 stopPreviewAndClose(device1); 1699 } 1700 } 1701 } 1702 1703 // It shouldn't be possible to start recording without enabling preview first. 1704 TEST_F(CameraHidlTest, startRecordingFail) { 1705 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1706 1707 for (const auto& name : cameraDeviceNames) { 1708 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1709 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1710 openCameraDevice(name, mProvider, &device1 /*out*/); 1711 ASSERT_NE(nullptr, device1.get()); 1712 1713 Return<bool> returnBoolStatus = device1->recordingEnabled(); 1714 ASSERT_TRUE(returnBoolStatus.isOk()); 1715 ASSERT_FALSE(returnBoolStatus); 1716 1717 Return<Status> returnStatus = device1->startRecording(); 1718 ASSERT_TRUE(returnStatus.isOk()); 1719 ASSERT_NE(Status::OK, returnStatus); 1720 1721 Return<void> ret = device1->close(); 1722 ASSERT_TRUE(ret.isOk()); 1723 } 1724 } 1725 } 1726 1727 // Check autofocus support if available. 1728 TEST_F(CameraHidlTest, autoFocus) { 1729 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1730 std::vector<const char*> focusModes = {CameraParameters::FOCUS_MODE_AUTO, 1731 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, 1732 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO}; 1733 1734 for (const auto& name : cameraDeviceNames) { 1735 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1736 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1737 openCameraDevice(name, mProvider, &device1 /*out*/); 1738 ASSERT_NE(nullptr, device1.get()); 1739 1740 CameraParameters cameraParams; 1741 getParameters(device1, &cameraParams /*out*/); 1742 1743 if (Status::OK != 1744 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) { 1745 Return<void> ret = device1->close(); 1746 ASSERT_TRUE(ret.isOk()); 1747 continue; 1748 } 1749 1750 sp<BufferItemConsumer> bufferItemConsumer; 1751 sp<BufferItemHander> bufferHandler; 1752 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1753 startPreview(device1); 1754 enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1); 1755 1756 for (auto& iter : focusModes) { 1757 if (Status::OK != isAutoFocusModeAvailable(cameraParams, iter)) { 1758 continue; 1759 } 1760 1761 cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter); 1762 setParameters(device1, cameraParams); 1763 { 1764 std::unique_lock<std::mutex> l(mLock); 1765 mNotifyMessage = NotifyCallbackMsg::ERROR; 1766 } 1767 1768 Return<Status> returnStatus = device1->autoFocus(); 1769 ASSERT_TRUE(returnStatus.isOk()); 1770 ASSERT_EQ(Status::OK, returnStatus); 1771 1772 { 1773 std::unique_lock<std::mutex> l(mLock); 1774 while (NotifyCallbackMsg::FOCUS != mNotifyMessage) { 1775 auto timeout = std::chrono::system_clock::now() + 1776 std::chrono::seconds(kAutoFocusTimeoutSec); 1777 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); 1778 } 1779 } 1780 } 1781 1782 disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1); 1783 stopPreviewAndClose(device1); 1784 } 1785 } 1786 } 1787 1788 // In case autofocus is supported verify that it can be cancelled. 1789 TEST_F(CameraHidlTest, cancelAutoFocus) { 1790 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1791 1792 for (const auto& name : cameraDeviceNames) { 1793 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1794 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1795 openCameraDevice(name, mProvider, &device1 /*out*/); 1796 ASSERT_NE(nullptr, device1.get()); 1797 1798 CameraParameters cameraParams; 1799 getParameters(device1, &cameraParams /*out*/); 1800 1801 if (Status::OK != 1802 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) { 1803 Return<void> ret = device1->close(); 1804 ASSERT_TRUE(ret.isOk()); 1805 continue; 1806 } 1807 1808 // It should be fine to call before preview starts. 1809 ASSERT_EQ(Status::OK, device1->cancelAutoFocus()); 1810 1811 sp<BufferItemConsumer> bufferItemConsumer; 1812 sp<BufferItemHander> bufferHandler; 1813 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1814 startPreview(device1); 1815 1816 // It should be fine to call after preview starts too. 1817 Return<Status> returnStatus = device1->cancelAutoFocus(); 1818 ASSERT_TRUE(returnStatus.isOk()); 1819 ASSERT_EQ(Status::OK, returnStatus); 1820 1821 returnStatus = device1->autoFocus(); 1822 ASSERT_TRUE(returnStatus.isOk()); 1823 ASSERT_EQ(Status::OK, returnStatus); 1824 1825 returnStatus = device1->cancelAutoFocus(); 1826 ASSERT_TRUE(returnStatus.isOk()); 1827 ASSERT_EQ(Status::OK, returnStatus); 1828 1829 stopPreviewAndClose(device1); 1830 } 1831 } 1832 } 1833 1834 // Check whether face detection is available and try to enable&disable. 1835 TEST_F(CameraHidlTest, sendCommandFaceDetection) { 1836 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1837 1838 for (const auto& name : cameraDeviceNames) { 1839 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1840 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1841 openCameraDevice(name, mProvider, &device1 /*out*/); 1842 ASSERT_NE(nullptr, device1.get()); 1843 1844 CameraParameters cameraParams; 1845 getParameters(device1, &cameraParams /*out*/); 1846 1847 int32_t hwFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW); 1848 int32_t swFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW); 1849 if ((0 >= hwFaces) && (0 >= swFaces)) { 1850 Return<void> ret = device1->close(); 1851 ASSERT_TRUE(ret.isOk()); 1852 continue; 1853 } 1854 1855 sp<BufferItemConsumer> bufferItemConsumer; 1856 sp<BufferItemHander> bufferHandler; 1857 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1858 startPreview(device1); 1859 1860 if (0 < hwFaces) { 1861 Return<Status> returnStatus = device1->sendCommand( 1862 CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_HW, 0); 1863 ASSERT_TRUE(returnStatus.isOk()); 1864 ASSERT_EQ(Status::OK, returnStatus); 1865 // TODO(epeev) : Enable and check for face notifications 1866 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION, 1867 CAMERA_FACE_DETECTION_HW, 0); 1868 ASSERT_TRUE(returnStatus.isOk()); 1869 ASSERT_EQ(Status::OK, returnStatus); 1870 } 1871 1872 if (0 < swFaces) { 1873 Return<Status> returnStatus = device1->sendCommand( 1874 CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_SW, 0); 1875 ASSERT_TRUE(returnStatus.isOk()); 1876 ASSERT_EQ(Status::OK, returnStatus); 1877 // TODO(epeev) : Enable and check for face notifications 1878 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION, 1879 CAMERA_FACE_DETECTION_SW, 0); 1880 ASSERT_TRUE(returnStatus.isOk()); 1881 ASSERT_EQ(Status::OK, returnStatus); 1882 } 1883 1884 stopPreviewAndClose(device1); 1885 } 1886 } 1887 } 1888 1889 // Check whether smooth zoom is available and try to enable&disable. 1890 TEST_F(CameraHidlTest, sendCommandSmoothZoom) { 1891 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1892 1893 for (const auto& name : cameraDeviceNames) { 1894 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1895 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1896 openCameraDevice(name, mProvider, &device1 /*out*/); 1897 ASSERT_NE(nullptr, device1.get()); 1898 1899 CameraParameters cameraParams; 1900 getParameters(device1, &cameraParams /*out*/); 1901 1902 const char* smoothZoomStr = 1903 cameraParams.get(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED); 1904 bool smoothZoomSupported = 1905 ((nullptr != smoothZoomStr) && (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0)) 1906 ? true 1907 : false; 1908 if (!smoothZoomSupported) { 1909 Return<void> ret = device1->close(); 1910 ASSERT_TRUE(ret.isOk()); 1911 continue; 1912 } 1913 1914 int32_t maxZoom = cameraParams.getInt(CameraParameters::KEY_MAX_ZOOM); 1915 ASSERT_TRUE(0 < maxZoom); 1916 1917 sp<BufferItemConsumer> bufferItemConsumer; 1918 sp<BufferItemHander> bufferHandler; 1919 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/); 1920 startPreview(device1); 1921 setParameters(device1, cameraParams); 1922 1923 Return<Status> returnStatus = 1924 device1->sendCommand(CommandType::START_SMOOTH_ZOOM, maxZoom, 0); 1925 ASSERT_TRUE(returnStatus.isOk()); 1926 ASSERT_EQ(Status::OK, returnStatus); 1927 // TODO(epeev) : Enable and check for face notifications 1928 returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM, 0, 0); 1929 ASSERT_TRUE(returnStatus.isOk()); 1930 ASSERT_EQ(Status::OK, returnStatus); 1931 1932 stopPreviewAndClose(device1); 1933 } 1934 } 1935 } 1936 1937 // Basic sanity tests related to camera parameters. 1938 TEST_F(CameraHidlTest, getSetParameters) { 1939 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1940 1941 for (const auto& name : cameraDeviceNames) { 1942 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) { 1943 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 1944 openCameraDevice(name, mProvider, &device1 /*out*/); 1945 ASSERT_NE(nullptr, device1.get()); 1946 1947 CameraParameters cameraParams; 1948 getParameters(device1, &cameraParams /*out*/); 1949 1950 int32_t width, height; 1951 cameraParams.getPictureSize(&width, &height); 1952 ASSERT_TRUE((0 < width) && (0 < height)); 1953 cameraParams.getPreviewSize(&width, &height); 1954 ASSERT_TRUE((0 < width) && (0 < height)); 1955 int32_t minFps, maxFps; 1956 cameraParams.getPreviewFpsRange(&minFps, &maxFps); 1957 ASSERT_TRUE((0 < minFps) && (0 < maxFps)); 1958 ASSERT_NE(nullptr, cameraParams.getPreviewFormat()); 1959 ASSERT_NE(nullptr, cameraParams.getPictureFormat()); 1960 ASSERT_TRUE( 1961 strcmp(CameraParameters::PIXEL_FORMAT_JPEG, cameraParams.getPictureFormat()) == 0); 1962 1963 const char* flashMode = cameraParams.get(CameraParameters::KEY_FLASH_MODE); 1964 ASSERT_TRUE((nullptr == flashMode) || 1965 (strcmp(CameraParameters::FLASH_MODE_OFF, flashMode) == 0)); 1966 1967 const char* wbMode = cameraParams.get(CameraParameters::KEY_WHITE_BALANCE); 1968 ASSERT_TRUE((nullptr == wbMode) || 1969 (strcmp(CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0)); 1970 1971 const char* effect = cameraParams.get(CameraParameters::KEY_EFFECT); 1972 ASSERT_TRUE((nullptr == effect) || 1973 (strcmp(CameraParameters::EFFECT_NONE, effect) == 0)); 1974 1975 ::android::Vector<Size> previewSizes; 1976 cameraParams.getSupportedPreviewSizes(previewSizes); 1977 ASSERT_FALSE(previewSizes.empty()); 1978 ::android::Vector<Size> pictureSizes; 1979 cameraParams.getSupportedPictureSizes(pictureSizes); 1980 ASSERT_FALSE(pictureSizes.empty()); 1981 const char* previewFormats = 1982 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS); 1983 ASSERT_NE(nullptr, previewFormats); 1984 ::android::String8 previewFormatsString(previewFormats); 1985 ASSERT_TRUE(previewFormatsString.contains(CameraParameters::PIXEL_FORMAT_YUV420SP)); 1986 ASSERT_NE(nullptr, cameraParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS)); 1987 ASSERT_NE(nullptr, 1988 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)); 1989 const char* focusModes = cameraParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES); 1990 ASSERT_NE(nullptr, focusModes); 1991 ::android::String8 focusModesString(focusModes); 1992 const char* focusMode = cameraParams.get(CameraParameters::KEY_FOCUS_MODE); 1993 ASSERT_NE(nullptr, focusMode); 1994 // Auto focus mode should be default 1995 if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) { 1996 ASSERT_TRUE(strcmp(CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0); 1997 } 1998 ASSERT_TRUE(0 < cameraParams.getInt(CameraParameters::KEY_FOCAL_LENGTH)); 1999 int32_t horizontalViewAngle = 2000 cameraParams.getInt(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE); 2001 ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle)); 2002 int32_t verticalViewAngle = 2003 cameraParams.getInt(CameraParameters::KEY_VERTICAL_VIEW_ANGLE); 2004 ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle)); 2005 int32_t jpegQuality = cameraParams.getInt(CameraParameters::KEY_JPEG_QUALITY); 2006 ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality)); 2007 int32_t jpegThumbQuality = 2008 cameraParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); 2009 ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality)); 2010 2011 cameraParams.setPictureSize(pictureSizes[0].width, pictureSizes[0].height); 2012 cameraParams.setPreviewSize(previewSizes[0].width, previewSizes[0].height); 2013 2014 setParameters(device1, cameraParams); 2015 getParameters(device1, &cameraParams /*out*/); 2016 2017 cameraParams.getPictureSize(&width, &height); 2018 ASSERT_TRUE((pictureSizes[0].width == width) && (pictureSizes[0].height == height)); 2019 cameraParams.getPreviewSize(&width, &height); 2020 ASSERT_TRUE((previewSizes[0].width == width) && (previewSizes[0].height == height)); 2021 2022 Return<void> ret = device1->close(); 2023 ASSERT_TRUE(ret.isOk()); 2024 } 2025 } 2026 } 2027 2028 // Verify that the static camera characteristics can be retrieved 2029 // successfully. 2030 TEST_F(CameraHidlTest, getCameraCharacteristics) { 2031 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2032 2033 for (const auto& name : cameraDeviceNames) { 2034 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2035 switch (deviceVersion) { 2036 case CAMERA_DEVICE_API_VERSION_3_4: 2037 case CAMERA_DEVICE_API_VERSION_3_3: 2038 case CAMERA_DEVICE_API_VERSION_3_2: { 2039 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 2040 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str()); 2041 Return<void> ret; 2042 ret = mProvider->getCameraDeviceInterface_V3_x( 2043 name, [&](auto status, const auto& device) { 2044 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2045 ASSERT_EQ(Status::OK, status); 2046 ASSERT_NE(device, nullptr); 2047 device3_x = device; 2048 }); 2049 ASSERT_TRUE(ret.isOk()); 2050 2051 ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) { 2052 ALOGI("getCameraCharacteristics returns status:%d", (int)status); 2053 ASSERT_EQ(Status::OK, status); 2054 const camera_metadata_t* metadata = (camera_metadata_t*)chars.data(); 2055 size_t expectedSize = chars.size(); 2056 int result = validate_camera_metadata_structure(metadata, &expectedSize); 2057 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 2058 size_t entryCount = get_camera_metadata_entry_count(metadata); 2059 // TODO: we can do better than 0 here. Need to check how many required 2060 // characteristics keys we've defined. 2061 ASSERT_GT(entryCount, 0u); 2062 ALOGI("getCameraCharacteristics metadata entry count is %zu", entryCount); 2063 2064 camera_metadata_ro_entry entry; 2065 int retcode = find_camera_metadata_ro_entry(metadata, 2066 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry); 2067 if ((0 == retcode) && (entry.count > 0)) { 2068 uint8_t hardwareLevel = entry.data.u8[0]; 2069 ASSERT_TRUE( 2070 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED || 2071 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL || 2072 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 || 2073 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL); 2074 } else { 2075 ADD_FAILURE() << "Get camera hardware level failed!"; 2076 } 2077 }); 2078 ASSERT_TRUE(ret.isOk()); 2079 } 2080 break; 2081 case CAMERA_DEVICE_API_VERSION_1_0: { 2082 //Not applicable 2083 } 2084 break; 2085 default: { 2086 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2087 ADD_FAILURE(); 2088 } 2089 break; 2090 } 2091 } 2092 } 2093 2094 //In case it is supported verify that torch can be enabled. 2095 //Check for corresponding toch callbacks as well. 2096 TEST_F(CameraHidlTest, setTorchMode) { 2097 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2098 bool torchControlSupported = false; 2099 Return<void> ret; 2100 2101 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) { 2102 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support); 2103 ASSERT_EQ(Status::OK, status); 2104 torchControlSupported = support; 2105 }); 2106 2107 sp<TorchProviderCb> cb = new TorchProviderCb(this); 2108 Return<Status> returnStatus = mProvider->setCallback(cb); 2109 ASSERT_TRUE(returnStatus.isOk()); 2110 ASSERT_EQ(Status::OK, returnStatus); 2111 2112 for (const auto& name : cameraDeviceNames) { 2113 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2114 switch (deviceVersion) { 2115 case CAMERA_DEVICE_API_VERSION_3_4: 2116 case CAMERA_DEVICE_API_VERSION_3_3: 2117 case CAMERA_DEVICE_API_VERSION_3_2: { 2118 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 2119 ALOGI("setTorchMode: Testing camera device %s", name.c_str()); 2120 ret = mProvider->getCameraDeviceInterface_V3_x( 2121 name, [&](auto status, const auto& device) { 2122 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2123 ASSERT_EQ(Status::OK, status); 2124 ASSERT_NE(device, nullptr); 2125 device3_x = device; 2126 }); 2127 ASSERT_TRUE(ret.isOk()); 2128 2129 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2130 returnStatus = device3_x->setTorchMode(TorchMode::ON); 2131 ASSERT_TRUE(returnStatus.isOk()); 2132 if (!torchControlSupported) { 2133 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus); 2134 } else { 2135 ASSERT_TRUE(returnStatus == Status::OK || 2136 returnStatus == Status::OPERATION_NOT_SUPPORTED); 2137 if (returnStatus == Status::OK) { 2138 { 2139 std::unique_lock<std::mutex> l(mTorchLock); 2140 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2141 auto timeout = std::chrono::system_clock::now() + 2142 std::chrono::seconds(kTorchTimeoutSec); 2143 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout)); 2144 } 2145 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus); 2146 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2147 } 2148 2149 returnStatus = device3_x->setTorchMode(TorchMode::OFF); 2150 ASSERT_TRUE(returnStatus.isOk()); 2151 ASSERT_EQ(Status::OK, returnStatus); 2152 2153 { 2154 std::unique_lock<std::mutex> l(mTorchLock); 2155 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2156 auto timeout = std::chrono::system_clock::now() + 2157 std::chrono::seconds(kTorchTimeoutSec); 2158 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout)); 2159 } 2160 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus); 2161 } 2162 } 2163 } 2164 } 2165 break; 2166 case CAMERA_DEVICE_API_VERSION_1_0: { 2167 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2168 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2169 ret = mProvider->getCameraDeviceInterface_V1_x( 2170 name, [&](auto status, const auto& device) { 2171 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 2172 ASSERT_EQ(Status::OK, status); 2173 ASSERT_NE(device, nullptr); 2174 device1 = device; 2175 }); 2176 ASSERT_TRUE(ret.isOk()); 2177 2178 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2179 returnStatus = device1->setTorchMode(TorchMode::ON); 2180 ASSERT_TRUE(returnStatus.isOk()); 2181 if (!torchControlSupported) { 2182 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus); 2183 } else { 2184 ASSERT_TRUE(returnStatus == Status::OK || 2185 returnStatus == Status::OPERATION_NOT_SUPPORTED); 2186 if (returnStatus == Status::OK) { 2187 { 2188 std::unique_lock<std::mutex> l(mTorchLock); 2189 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2190 auto timeout = std::chrono::system_clock::now() + 2191 std::chrono::seconds(kTorchTimeoutSec); 2192 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, 2193 timeout)); 2194 } 2195 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus); 2196 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2197 } 2198 2199 returnStatus = device1->setTorchMode(TorchMode::OFF); 2200 ASSERT_TRUE(returnStatus.isOk()); 2201 ASSERT_EQ(Status::OK, returnStatus); 2202 2203 { 2204 std::unique_lock<std::mutex> l(mTorchLock); 2205 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2206 auto timeout = std::chrono::system_clock::now() + 2207 std::chrono::seconds(kTorchTimeoutSec); 2208 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, 2209 timeout)); 2210 } 2211 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus); 2212 } 2213 } 2214 } 2215 ret = device1->close(); 2216 ASSERT_TRUE(ret.isOk()); 2217 } 2218 break; 2219 default: { 2220 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2221 ADD_FAILURE(); 2222 } 2223 break; 2224 } 2225 } 2226 2227 returnStatus = mProvider->setCallback(nullptr); 2228 ASSERT_TRUE(returnStatus.isOk()); 2229 ASSERT_EQ(Status::OK, returnStatus); 2230 } 2231 2232 // Check dump functionality. 2233 TEST_F(CameraHidlTest, dumpState) { 2234 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2235 Return<void> ret; 2236 2237 for (const auto& name : cameraDeviceNames) { 2238 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2239 switch (deviceVersion) { 2240 case CAMERA_DEVICE_API_VERSION_3_4: 2241 case CAMERA_DEVICE_API_VERSION_3_3: 2242 case CAMERA_DEVICE_API_VERSION_3_2: { 2243 ::android::sp<ICameraDevice> device3_x; 2244 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2245 ret = mProvider->getCameraDeviceInterface_V3_x( 2246 name, [&](auto status, const auto& device) { 2247 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2248 ASSERT_EQ(Status::OK, status); 2249 ASSERT_NE(device, nullptr); 2250 device3_x = device; 2251 }); 2252 ASSERT_TRUE(ret.isOk()); 2253 2254 native_handle_t* raw_handle = native_handle_create(1, 0); 2255 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2256 ASSERT_GE(raw_handle->data[0], 0); 2257 hidl_handle handle = raw_handle; 2258 ret = device3_x->dumpState(handle); 2259 ASSERT_TRUE(ret.isOk()); 2260 close(raw_handle->data[0]); 2261 native_handle_delete(raw_handle); 2262 } 2263 break; 2264 case CAMERA_DEVICE_API_VERSION_1_0: { 2265 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2266 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2267 ret = mProvider->getCameraDeviceInterface_V1_x( 2268 name, [&](auto status, const auto& device) { 2269 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 2270 ASSERT_EQ(Status::OK, status); 2271 ASSERT_NE(device, nullptr); 2272 device1 = device; 2273 }); 2274 ASSERT_TRUE(ret.isOk()); 2275 2276 native_handle_t* raw_handle = native_handle_create(1, 0); 2277 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2278 ASSERT_GE(raw_handle->data[0], 0); 2279 hidl_handle handle = raw_handle; 2280 Return<Status> returnStatus = device1->dumpState(handle); 2281 ASSERT_TRUE(returnStatus.isOk()); 2282 ASSERT_EQ(Status::OK, returnStatus); 2283 close(raw_handle->data[0]); 2284 native_handle_delete(raw_handle); 2285 } 2286 break; 2287 default: { 2288 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2289 ADD_FAILURE(); 2290 } 2291 break; 2292 } 2293 } 2294 } 2295 2296 // Open, dumpStates, then close 2297 TEST_F(CameraHidlTest, openClose) { 2298 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2299 Return<void> ret; 2300 2301 for (const auto& name : cameraDeviceNames) { 2302 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2303 switch (deviceVersion) { 2304 case CAMERA_DEVICE_API_VERSION_3_4: 2305 case CAMERA_DEVICE_API_VERSION_3_3: 2306 case CAMERA_DEVICE_API_VERSION_3_2: { 2307 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 2308 ALOGI("openClose: Testing camera device %s", name.c_str()); 2309 ret = mProvider->getCameraDeviceInterface_V3_x( 2310 name, [&](auto status, const auto& device) { 2311 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2312 ASSERT_EQ(Status::OK, status); 2313 ASSERT_NE(device, nullptr); 2314 device3_x = device; 2315 }); 2316 ASSERT_TRUE(ret.isOk()); 2317 2318 sp<EmptyDeviceCb> cb = new EmptyDeviceCb; 2319 sp<ICameraDeviceSession> session; 2320 ret = device3_x->open(cb, [&](auto status, const auto& newSession) { 2321 ALOGI("device::open returns status:%d", (int)status); 2322 ASSERT_EQ(Status::OK, status); 2323 ASSERT_NE(newSession, nullptr); 2324 session = newSession; 2325 }); 2326 ASSERT_TRUE(ret.isOk()); 2327 // Ensure that a device labeling itself as 3.3/3.4 can have its session interface 2328 // cast the 3.3/3.4 interface, and that lower versions can't be cast to it. 2329 sp<device::V3_3::ICameraDeviceSession> sessionV3_3; 2330 sp<device::V3_4::ICameraDeviceSession> sessionV3_4; 2331 castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4); 2332 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { 2333 ASSERT_TRUE(sessionV3_4.get() != nullptr); 2334 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) { 2335 ASSERT_TRUE(sessionV3_3.get() != nullptr); 2336 } else { 2337 ASSERT_TRUE(sessionV3_3.get() == nullptr); 2338 } 2339 native_handle_t* raw_handle = native_handle_create(1, 0); 2340 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2341 ASSERT_GE(raw_handle->data[0], 0); 2342 hidl_handle handle = raw_handle; 2343 ret = device3_x->dumpState(handle); 2344 ASSERT_TRUE(ret.isOk()); 2345 close(raw_handle->data[0]); 2346 native_handle_delete(raw_handle); 2347 2348 ret = session->close(); 2349 ASSERT_TRUE(ret.isOk()); 2350 // TODO: test all session API calls return INTERNAL_ERROR after close 2351 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope 2352 } 2353 break; 2354 case CAMERA_DEVICE_API_VERSION_1_0: { 2355 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2356 openCameraDevice(name, mProvider, &device1 /*out*/); 2357 ASSERT_NE(nullptr, device1.get()); 2358 2359 native_handle_t* raw_handle = native_handle_create(1, 0); 2360 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2361 ASSERT_GE(raw_handle->data[0], 0); 2362 hidl_handle handle = raw_handle; 2363 Return<Status> returnStatus = device1->dumpState(handle); 2364 ASSERT_TRUE(returnStatus.isOk()); 2365 ASSERT_EQ(Status::OK, returnStatus); 2366 close(raw_handle->data[0]); 2367 native_handle_delete(raw_handle); 2368 2369 ret = device1->close(); 2370 ASSERT_TRUE(ret.isOk()); 2371 } 2372 break; 2373 default: { 2374 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2375 ADD_FAILURE(); 2376 } 2377 break; 2378 } 2379 } 2380 } 2381 2382 // Check whether all common default request settings can be sucessfully 2383 // constructed. 2384 TEST_F(CameraHidlTest, constructDefaultRequestSettings) { 2385 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2386 2387 for (const auto& name : cameraDeviceNames) { 2388 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2389 switch (deviceVersion) { 2390 case CAMERA_DEVICE_API_VERSION_3_4: 2391 case CAMERA_DEVICE_API_VERSION_3_3: 2392 case CAMERA_DEVICE_API_VERSION_3_2: { 2393 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 2394 Return<void> ret; 2395 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str()); 2396 ret = mProvider->getCameraDeviceInterface_V3_x( 2397 name, [&](auto status, const auto& device) { 2398 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2399 ASSERT_EQ(Status::OK, status); 2400 ASSERT_NE(device, nullptr); 2401 device3_x = device; 2402 }); 2403 ASSERT_TRUE(ret.isOk()); 2404 2405 sp<EmptyDeviceCb> cb = new EmptyDeviceCb; 2406 sp<ICameraDeviceSession> session; 2407 ret = device3_x->open(cb, [&](auto status, const auto& newSession) { 2408 ALOGI("device::open returns status:%d", (int)status); 2409 ASSERT_EQ(Status::OK, status); 2410 ASSERT_NE(newSession, nullptr); 2411 session = newSession; 2412 }); 2413 ASSERT_TRUE(ret.isOk()); 2414 2415 for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW; 2416 t <= (uint32_t)RequestTemplate::MANUAL; t++) { 2417 RequestTemplate reqTemplate = (RequestTemplate)t; 2418 ret = 2419 session->constructDefaultRequestSettings( 2420 reqTemplate, [&](auto status, const auto& req) { 2421 ALOGI("constructDefaultRequestSettings returns status:%d", 2422 (int)status); 2423 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG || 2424 reqTemplate == RequestTemplate::MANUAL) { 2425 // optional templates 2426 ASSERT_TRUE((status == Status::OK) || 2427 (status == Status::ILLEGAL_ARGUMENT)); 2428 } else { 2429 ASSERT_EQ(Status::OK, status); 2430 } 2431 2432 if (status == Status::OK) { 2433 const camera_metadata_t* metadata = 2434 (camera_metadata_t*) req.data(); 2435 size_t expectedSize = req.size(); 2436 int result = validate_camera_metadata_structure( 2437 metadata, &expectedSize); 2438 ASSERT_TRUE((result == 0) || 2439 (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 2440 size_t entryCount = 2441 get_camera_metadata_entry_count(metadata); 2442 // TODO: we can do better than 0 here. Need to check how many required 2443 // request keys we've defined for each template 2444 ASSERT_GT(entryCount, 0u); 2445 ALOGI("template %u metadata entry count is %zu", 2446 t, entryCount); 2447 } else { 2448 ASSERT_EQ(0u, req.size()); 2449 } 2450 }); 2451 ASSERT_TRUE(ret.isOk()); 2452 } 2453 ret = session->close(); 2454 ASSERT_TRUE(ret.isOk()); 2455 } 2456 break; 2457 case CAMERA_DEVICE_API_VERSION_1_0: { 2458 //Not applicable 2459 } 2460 break; 2461 default: { 2462 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2463 ADD_FAILURE(); 2464 } 2465 break; 2466 } 2467 } 2468 } 2469 2470 2471 // Verify that all supported stream formats and sizes can be configured 2472 // successfully. 2473 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { 2474 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2475 std::vector<AvailableStream> outputStreams; 2476 2477 for (const auto& name : cameraDeviceNames) { 2478 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2479 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2480 continue; 2481 } else if (deviceVersion <= 0) { 2482 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2483 ADD_FAILURE(); 2484 return; 2485 } 2486 2487 camera_metadata_t* staticMeta; 2488 Return<void> ret; 2489 sp<ICameraDeviceSession> session; 2490 sp<device::V3_3::ICameraDeviceSession> session3_3; 2491 sp<device::V3_4::ICameraDeviceSession> session3_4; 2492 openEmptyDeviceSession(name, mProvider, 2493 &session /*out*/, &staticMeta /*out*/); 2494 castSession(session, deviceVersion, &session3_3, &session3_4); 2495 2496 outputStreams.clear(); 2497 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); 2498 ASSERT_NE(0u, outputStreams.size()); 2499 2500 int32_t streamId = 0; 2501 for (auto& it : outputStreams) { 2502 V3_2::Stream stream3_2; 2503 bool isJpeg = static_cast<PixelFormat>(it.format) == PixelFormat::BLOB; 2504 stream3_2 = {streamId, 2505 StreamType::OUTPUT, 2506 static_cast<uint32_t>(it.width), 2507 static_cast<uint32_t>(it.height), 2508 static_cast<PixelFormat>(it.format), 2509 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2510 (isJpeg) ? static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF) : 0, 2511 StreamRotation::ROTATION_0}; 2512 ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2}; 2513 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 2514 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 2515 createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, 2516 &config3_2, &config3_4); 2517 if (session3_4 != nullptr) { 2518 ret = session3_4->configureStreams_3_4(config3_4, 2519 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { 2520 ASSERT_EQ(Status::OK, s); 2521 ASSERT_EQ(1u, halConfig.streams.size()); 2522 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId); 2523 }); 2524 } else if (session3_3 != nullptr) { 2525 ret = session3_3->configureStreams_3_3(config3_2, 2526 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2527 ASSERT_EQ(Status::OK, s); 2528 ASSERT_EQ(1u, halConfig.streams.size()); 2529 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); 2530 }); 2531 } else { 2532 ret = session->configureStreams(config3_2, 2533 [streamId](Status s, HalStreamConfiguration halConfig) { 2534 ASSERT_EQ(Status::OK, s); 2535 ASSERT_EQ(1u, halConfig.streams.size()); 2536 ASSERT_EQ(halConfig.streams[0].id, streamId); 2537 }); 2538 } 2539 ASSERT_TRUE(ret.isOk()); 2540 streamId++; 2541 } 2542 2543 free_camera_metadata(staticMeta); 2544 ret = session->close(); 2545 ASSERT_TRUE(ret.isOk()); 2546 } 2547 } 2548 2549 // Check for correct handling of invalid/incorrect configuration parameters. 2550 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { 2551 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2552 std::vector<AvailableStream> outputStreams; 2553 2554 for (const auto& name : cameraDeviceNames) { 2555 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2556 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2557 continue; 2558 } else if (deviceVersion <= 0) { 2559 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2560 ADD_FAILURE(); 2561 return; 2562 } 2563 2564 camera_metadata_t* staticMeta; 2565 Return<void> ret; 2566 sp<ICameraDeviceSession> session; 2567 sp<device::V3_3::ICameraDeviceSession> session3_3; 2568 sp<device::V3_4::ICameraDeviceSession> session3_4; 2569 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2570 castSession(session, deviceVersion, &session3_3, &session3_4); 2571 2572 outputStreams.clear(); 2573 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); 2574 ASSERT_NE(0u, outputStreams.size()); 2575 2576 int32_t streamId = 0; 2577 V3_2::Stream stream3_2 = {streamId++, 2578 StreamType::OUTPUT, 2579 static_cast<uint32_t>(0), 2580 static_cast<uint32_t>(0), 2581 static_cast<PixelFormat>(outputStreams[0].format), 2582 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2583 0, 2584 StreamRotation::ROTATION_0}; 2585 ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream3_2}; 2586 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 2587 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 2588 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 2589 &config3_2, &config3_4); 2590 if(session3_4 != nullptr) { 2591 ret = session3_4->configureStreams_3_4(config3_4, 2592 [](Status s, device::V3_4::HalStreamConfiguration) { 2593 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2594 (Status::INTERNAL_ERROR == s)); 2595 }); 2596 } else if(session3_3 != nullptr) { 2597 ret = session3_3->configureStreams_3_3(config3_2, 2598 [](Status s, device::V3_3::HalStreamConfiguration) { 2599 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2600 (Status::INTERNAL_ERROR == s)); 2601 }); 2602 } else { 2603 ret = session->configureStreams(config3_2, 2604 [](Status s, HalStreamConfiguration) { 2605 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2606 (Status::INTERNAL_ERROR == s)); 2607 }); 2608 } 2609 ASSERT_TRUE(ret.isOk()); 2610 2611 stream3_2 = {streamId++, 2612 StreamType::OUTPUT, 2613 static_cast<uint32_t>(UINT32_MAX), 2614 static_cast<uint32_t>(UINT32_MAX), 2615 static_cast<PixelFormat>(outputStreams[0].format), 2616 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2617 0, 2618 StreamRotation::ROTATION_0}; 2619 streams[0] = stream3_2; 2620 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 2621 &config3_2, &config3_4); 2622 if(session3_4 != nullptr) { 2623 ret = session3_4->configureStreams_3_4(config3_4, [](Status s, 2624 device::V3_4::HalStreamConfiguration) { 2625 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2626 }); 2627 } else if(session3_3 != nullptr) { 2628 ret = session3_3->configureStreams_3_3(config3_2, [](Status s, 2629 device::V3_3::HalStreamConfiguration) { 2630 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2631 }); 2632 } else { 2633 ret = session->configureStreams(config3_2, [](Status s, 2634 HalStreamConfiguration) { 2635 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2636 }); 2637 } 2638 ASSERT_TRUE(ret.isOk()); 2639 2640 for (auto& it : outputStreams) { 2641 stream3_2 = {streamId++, 2642 StreamType::OUTPUT, 2643 static_cast<uint32_t>(it.width), 2644 static_cast<uint32_t>(it.height), 2645 static_cast<PixelFormat>(UINT32_MAX), 2646 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2647 0, 2648 StreamRotation::ROTATION_0}; 2649 streams[0] = stream3_2; 2650 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 2651 &config3_2, &config3_4); 2652 if(session3_4 != nullptr) { 2653 ret = session3_4->configureStreams_3_4(config3_4, 2654 [](Status s, device::V3_4::HalStreamConfiguration) { 2655 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2656 }); 2657 } else if(session3_3 != nullptr) { 2658 ret = session3_3->configureStreams_3_3(config3_2, 2659 [](Status s, device::V3_3::HalStreamConfiguration) { 2660 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2661 }); 2662 } else { 2663 ret = session->configureStreams(config3_2, 2664 [](Status s, HalStreamConfiguration) { 2665 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2666 }); 2667 } 2668 ASSERT_TRUE(ret.isOk()); 2669 2670 stream3_2 = {streamId++, 2671 StreamType::OUTPUT, 2672 static_cast<uint32_t>(it.width), 2673 static_cast<uint32_t>(it.height), 2674 static_cast<PixelFormat>(it.format), 2675 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2676 0, 2677 static_cast<StreamRotation>(UINT32_MAX)}; 2678 streams[0] = stream3_2; 2679 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 2680 &config3_2, &config3_4); 2681 if(session3_4 != nullptr) { 2682 ret = session3_4->configureStreams_3_4(config3_4, 2683 [](Status s, device::V3_4::HalStreamConfiguration) { 2684 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2685 }); 2686 } else if(session3_3 != nullptr) { 2687 ret = session3_3->configureStreams_3_3(config3_2, 2688 [](Status s, device::V3_3::HalStreamConfiguration) { 2689 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2690 }); 2691 } else { 2692 ret = session->configureStreams(config3_2, 2693 [](Status s, HalStreamConfiguration) { 2694 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2695 }); 2696 } 2697 ASSERT_TRUE(ret.isOk()); 2698 } 2699 2700 free_camera_metadata(staticMeta); 2701 ret = session->close(); 2702 ASSERT_TRUE(ret.isOk()); 2703 } 2704 } 2705 2706 // Check whether all supported ZSL output stream combinations can be 2707 // configured successfully. 2708 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { 2709 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2710 std::vector<AvailableStream> inputStreams; 2711 std::vector<AvailableZSLInputOutput> inputOutputMap; 2712 2713 for (const auto& name : cameraDeviceNames) { 2714 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2715 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2716 continue; 2717 } else if (deviceVersion <= 0) { 2718 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2719 ADD_FAILURE(); 2720 return; 2721 } 2722 2723 camera_metadata_t* staticMeta; 2724 Return<void> ret; 2725 sp<ICameraDeviceSession> session; 2726 sp<device::V3_3::ICameraDeviceSession> session3_3; 2727 sp<device::V3_4::ICameraDeviceSession> session3_4; 2728 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2729 castSession(session, deviceVersion, &session3_3, &session3_4); 2730 2731 Status rc = isZSLModeAvailable(staticMeta); 2732 if (Status::METHOD_NOT_SUPPORTED == rc) { 2733 ret = session->close(); 2734 ASSERT_TRUE(ret.isOk()); 2735 continue; 2736 } 2737 ASSERT_EQ(Status::OK, rc); 2738 2739 inputStreams.clear(); 2740 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams)); 2741 ASSERT_NE(0u, inputStreams.size()); 2742 2743 inputOutputMap.clear(); 2744 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap)); 2745 ASSERT_NE(0u, inputOutputMap.size()); 2746 2747 int32_t streamId = 0; 2748 for (auto& inputIter : inputOutputMap) { 2749 AvailableStream input; 2750 ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, 2751 input)); 2752 ASSERT_NE(0u, inputStreams.size()); 2753 2754 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, 2755 inputIter.outputFormat}; 2756 std::vector<AvailableStream> outputStreams; 2757 ASSERT_EQ(Status::OK, 2758 getAvailableOutputStreams(staticMeta, outputStreams, 2759 &outputThreshold)); 2760 for (auto& outputIter : outputStreams) { 2761 V3_2::Stream zslStream = {streamId++, 2762 StreamType::OUTPUT, 2763 static_cast<uint32_t>(input.width), 2764 static_cast<uint32_t>(input.height), 2765 static_cast<PixelFormat>(input.format), 2766 GRALLOC_USAGE_HW_CAMERA_ZSL, 2767 0, 2768 StreamRotation::ROTATION_0}; 2769 V3_2::Stream inputStream = {streamId++, 2770 StreamType::INPUT, 2771 static_cast<uint32_t>(input.width), 2772 static_cast<uint32_t>(input.height), 2773 static_cast<PixelFormat>(input.format), 2774 0, 2775 0, 2776 StreamRotation::ROTATION_0}; 2777 V3_2::Stream outputStream = {streamId++, 2778 StreamType::OUTPUT, 2779 static_cast<uint32_t>(outputIter.width), 2780 static_cast<uint32_t>(outputIter.height), 2781 static_cast<PixelFormat>(outputIter.format), 2782 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2783 0, 2784 StreamRotation::ROTATION_0}; 2785 2786 ::android::hardware::hidl_vec<V3_2::Stream> streams = {inputStream, zslStream, 2787 outputStream}; 2788 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 2789 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 2790 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 2791 &config3_2, &config3_4); 2792 if (session3_4 != nullptr) { 2793 ret = session3_4->configureStreams_3_4(config3_4, 2794 [](Status s, device::V3_4::HalStreamConfiguration halConfig) { 2795 ASSERT_EQ(Status::OK, s); 2796 ASSERT_EQ(3u, halConfig.streams.size()); 2797 }); 2798 } else if (session3_3 != nullptr) { 2799 ret = session3_3->configureStreams_3_3(config3_2, 2800 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2801 ASSERT_EQ(Status::OK, s); 2802 ASSERT_EQ(3u, halConfig.streams.size()); 2803 }); 2804 } else { 2805 ret = session->configureStreams(config3_2, 2806 [](Status s, HalStreamConfiguration halConfig) { 2807 ASSERT_EQ(Status::OK, s); 2808 ASSERT_EQ(3u, halConfig.streams.size()); 2809 }); 2810 } 2811 ASSERT_TRUE(ret.isOk()); 2812 } 2813 } 2814 2815 free_camera_metadata(staticMeta); 2816 ret = session->close(); 2817 ASSERT_TRUE(ret.isOk()); 2818 } 2819 } 2820 2821 // Check wehether session parameters are supported. If Hal support for them 2822 // exist, then try to configure a preview stream using them. 2823 TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) { 2824 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2825 std::vector<AvailableStream> outputPreviewStreams; 2826 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 2827 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2828 2829 for (const auto& name : cameraDeviceNames) { 2830 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2831 if (deviceVersion <= 0) { 2832 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2833 ADD_FAILURE(); 2834 return; 2835 } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) { 2836 continue; 2837 } 2838 2839 camera_metadata_t* staticMetaBuffer; 2840 Return<void> ret; 2841 sp<ICameraDeviceSession> session; 2842 sp<device::V3_3::ICameraDeviceSession> session3_3; 2843 sp<device::V3_4::ICameraDeviceSession> session3_4; 2844 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); 2845 castSession(session, deviceVersion, &session3_3, &session3_4); 2846 ASSERT_NE(session3_4, nullptr); 2847 2848 std::unordered_set<int32_t> availableSessionKeys; 2849 auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS, 2850 &availableSessionKeys); 2851 ASSERT_TRUE(Status::OK == rc); 2852 if (availableSessionKeys.empty()) { 2853 free_camera_metadata(staticMetaBuffer); 2854 ret = session->close(); 2855 ASSERT_TRUE(ret.isOk()); 2856 continue; 2857 } 2858 2859 android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings; 2860 android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams; 2861 constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW, 2862 &previewRequestSettings, &sessionParams); 2863 if (sessionParams.isEmpty()) { 2864 free_camera_metadata(staticMetaBuffer); 2865 ret = session->close(); 2866 ASSERT_TRUE(ret.isOk()); 2867 continue; 2868 } 2869 2870 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams, 2871 &previewThreshold)); 2872 ASSERT_NE(0u, outputPreviewStreams.size()); 2873 2874 V3_4::Stream previewStream; 2875 previewStream.v3_2 = {0, 2876 StreamType::OUTPUT, 2877 static_cast<uint32_t>(outputPreviewStreams[0].width), 2878 static_cast<uint32_t>(outputPreviewStreams[0].height), 2879 static_cast<PixelFormat>(outputPreviewStreams[0].format), 2880 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2881 0, 2882 StreamRotation::ROTATION_0}; 2883 ::android::hardware::hidl_vec<V3_4::Stream> streams = {previewStream}; 2884 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2885 config.streams = streams; 2886 config.operationMode = StreamConfigurationMode::NORMAL_MODE; 2887 const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock(); 2888 config.sessionParams.setToExternal( 2889 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (sessionParamsBuffer)), 2890 get_camera_metadata_size(sessionParamsBuffer)); 2891 ret = session3_4->configureStreams_3_4(config, 2892 [](Status s, device::V3_4::HalStreamConfiguration halConfig) { 2893 ASSERT_EQ(Status::OK, s); 2894 ASSERT_EQ(1u, halConfig.streams.size()); 2895 }); 2896 ASSERT_TRUE(ret.isOk()); 2897 2898 free_camera_metadata(staticMetaBuffer); 2899 ret = session->close(); 2900 ASSERT_TRUE(ret.isOk()); 2901 } 2902 } 2903 2904 // Verify that all supported preview + still capture stream combinations 2905 // can be configured successfully. 2906 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { 2907 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2908 std::vector<AvailableStream> outputBlobStreams; 2909 std::vector<AvailableStream> outputPreviewStreams; 2910 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 2911 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2912 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX, 2913 static_cast<int32_t>(PixelFormat::BLOB)}; 2914 2915 for (const auto& name : cameraDeviceNames) { 2916 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2917 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2918 continue; 2919 } else if (deviceVersion <= 0) { 2920 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2921 ADD_FAILURE(); 2922 return; 2923 } 2924 2925 camera_metadata_t* staticMeta; 2926 Return<void> ret; 2927 sp<ICameraDeviceSession> session; 2928 sp<device::V3_3::ICameraDeviceSession> session3_3; 2929 sp<device::V3_4::ICameraDeviceSession> session3_4; 2930 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2931 castSession(session, deviceVersion, &session3_3, &session3_4); 2932 2933 outputBlobStreams.clear(); 2934 ASSERT_EQ(Status::OK, 2935 getAvailableOutputStreams(staticMeta, outputBlobStreams, 2936 &blobThreshold)); 2937 ASSERT_NE(0u, outputBlobStreams.size()); 2938 2939 outputPreviewStreams.clear(); 2940 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams, 2941 &previewThreshold)); 2942 ASSERT_NE(0u, outputPreviewStreams.size()); 2943 2944 int32_t streamId = 0; 2945 for (auto& blobIter : outputBlobStreams) { 2946 for (auto& previewIter : outputPreviewStreams) { 2947 V3_2::Stream previewStream = {streamId++, 2948 StreamType::OUTPUT, 2949 static_cast<uint32_t>(previewIter.width), 2950 static_cast<uint32_t>(previewIter.height), 2951 static_cast<PixelFormat>(previewIter.format), 2952 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2953 0, 2954 StreamRotation::ROTATION_0}; 2955 V3_2::Stream blobStream = {streamId++, 2956 StreamType::OUTPUT, 2957 static_cast<uint32_t>(blobIter.width), 2958 static_cast<uint32_t>(blobIter.height), 2959 static_cast<PixelFormat>(blobIter.format), 2960 GRALLOC1_CONSUMER_USAGE_CPU_READ, 2961 static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF), 2962 StreamRotation::ROTATION_0}; 2963 ::android::hardware::hidl_vec<V3_2::Stream> streams = {previewStream, 2964 blobStream}; 2965 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 2966 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 2967 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 2968 &config3_2, &config3_4); 2969 if (session3_4 != nullptr) { 2970 ret = session3_4->configureStreams_3_4(config3_4, 2971 [](Status s, device::V3_4::HalStreamConfiguration halConfig) { 2972 ASSERT_EQ(Status::OK, s); 2973 ASSERT_EQ(2u, halConfig.streams.size()); 2974 }); 2975 } else if (session3_3 != nullptr) { 2976 ret = session3_3->configureStreams_3_3(config3_2, 2977 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2978 ASSERT_EQ(Status::OK, s); 2979 ASSERT_EQ(2u, halConfig.streams.size()); 2980 }); 2981 } else { 2982 ret = session->configureStreams(config3_2, 2983 [](Status s, HalStreamConfiguration halConfig) { 2984 ASSERT_EQ(Status::OK, s); 2985 ASSERT_EQ(2u, halConfig.streams.size()); 2986 }); 2987 } 2988 ASSERT_TRUE(ret.isOk()); 2989 } 2990 } 2991 2992 free_camera_metadata(staticMeta); 2993 ret = session->close(); 2994 ASSERT_TRUE(ret.isOk()); 2995 } 2996 } 2997 2998 // In case constrained mode is supported, test whether it can be 2999 // configured. Additionally check for common invalid inputs when 3000 // using this mode. 3001 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { 3002 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3003 3004 for (const auto& name : cameraDeviceNames) { 3005 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3006 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3007 continue; 3008 } else if (deviceVersion <= 0) { 3009 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3010 ADD_FAILURE(); 3011 return; 3012 } 3013 3014 camera_metadata_t* staticMeta; 3015 Return<void> ret; 3016 sp<ICameraDeviceSession> session; 3017 sp<device::V3_3::ICameraDeviceSession> session3_3; 3018 sp<device::V3_4::ICameraDeviceSession> session3_4; 3019 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 3020 castSession(session, deviceVersion, &session3_3, &session3_4); 3021 3022 Status rc = isConstrainedModeAvailable(staticMeta); 3023 if (Status::METHOD_NOT_SUPPORTED == rc) { 3024 ret = session->close(); 3025 ASSERT_TRUE(ret.isOk()); 3026 continue; 3027 } 3028 ASSERT_EQ(Status::OK, rc); 3029 3030 AvailableStream hfrStream; 3031 rc = pickConstrainedModeSize(staticMeta, hfrStream); 3032 ASSERT_EQ(Status::OK, rc); 3033 3034 int32_t streamId = 0; 3035 V3_2::Stream stream = {streamId, 3036 StreamType::OUTPUT, 3037 static_cast<uint32_t>(hfrStream.width), 3038 static_cast<uint32_t>(hfrStream.height), 3039 static_cast<PixelFormat>(hfrStream.format), 3040 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 3041 0, 3042 StreamRotation::ROTATION_0}; 3043 ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream}; 3044 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 3045 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 3046 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, 3047 &config3_2, &config3_4); 3048 if (session3_4 != nullptr) { 3049 ret = session3_4->configureStreams_3_4(config3_4, 3050 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { 3051 ASSERT_EQ(Status::OK, s); 3052 ASSERT_EQ(1u, halConfig.streams.size()); 3053 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId); 3054 }); 3055 } else if (session3_3 != nullptr) { 3056 ret = session3_3->configureStreams_3_3(config3_2, 3057 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { 3058 ASSERT_EQ(Status::OK, s); 3059 ASSERT_EQ(1u, halConfig.streams.size()); 3060 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); 3061 }); 3062 } else { 3063 ret = session->configureStreams(config3_2, 3064 [streamId](Status s, HalStreamConfiguration halConfig) { 3065 ASSERT_EQ(Status::OK, s); 3066 ASSERT_EQ(1u, halConfig.streams.size()); 3067 ASSERT_EQ(halConfig.streams[0].id, streamId); 3068 }); 3069 } 3070 ASSERT_TRUE(ret.isOk()); 3071 3072 stream = {streamId++, 3073 StreamType::OUTPUT, 3074 static_cast<uint32_t>(0), 3075 static_cast<uint32_t>(0), 3076 static_cast<PixelFormat>(hfrStream.format), 3077 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 3078 0, 3079 StreamRotation::ROTATION_0}; 3080 streams[0] = stream; 3081 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, 3082 &config3_2, &config3_4); 3083 if (session3_4 != nullptr) { 3084 ret = session3_4->configureStreams_3_4(config3_4, 3085 [](Status s, device::V3_4::HalStreamConfiguration) { 3086 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 3087 (Status::INTERNAL_ERROR == s)); 3088 }); 3089 } else if (session3_3 != nullptr) { 3090 ret = session3_3->configureStreams_3_3(config3_2, 3091 [](Status s, device::V3_3::HalStreamConfiguration) { 3092 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 3093 (Status::INTERNAL_ERROR == s)); 3094 }); 3095 } else { 3096 ret = session->configureStreams(config3_2, 3097 [](Status s, HalStreamConfiguration) { 3098 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 3099 (Status::INTERNAL_ERROR == s)); 3100 }); 3101 } 3102 ASSERT_TRUE(ret.isOk()); 3103 3104 stream = {streamId++, 3105 StreamType::OUTPUT, 3106 static_cast<uint32_t>(UINT32_MAX), 3107 static_cast<uint32_t>(UINT32_MAX), 3108 static_cast<PixelFormat>(hfrStream.format), 3109 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 3110 0, 3111 StreamRotation::ROTATION_0}; 3112 streams[0] = stream; 3113 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, 3114 &config3_2, &config3_4); 3115 if (session3_4 != nullptr) { 3116 ret = session3_4->configureStreams_3_4(config3_4, 3117 [](Status s, device::V3_4::HalStreamConfiguration) { 3118 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 3119 }); 3120 } else if (session3_3 != nullptr) { 3121 ret = session3_3->configureStreams_3_3(config3_2, 3122 [](Status s, device::V3_3::HalStreamConfiguration) { 3123 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 3124 }); 3125 } else { 3126 ret = session->configureStreams(config3_2, 3127 [](Status s, HalStreamConfiguration) { 3128 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 3129 }); 3130 } 3131 ASSERT_TRUE(ret.isOk()); 3132 3133 stream = {streamId++, 3134 StreamType::OUTPUT, 3135 static_cast<uint32_t>(hfrStream.width), 3136 static_cast<uint32_t>(hfrStream.height), 3137 static_cast<PixelFormat>(UINT32_MAX), 3138 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 3139 0, 3140 StreamRotation::ROTATION_0}; 3141 streams[0] = stream; 3142 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, 3143 &config3_2, &config3_4); 3144 if (session3_4 != nullptr) { 3145 ret = session3_4->configureStreams_3_4(config3_4, 3146 [](Status s, device::V3_4::HalStreamConfiguration) { 3147 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 3148 }); 3149 } else if (session3_3 != nullptr) { 3150 ret = session3_3->configureStreams_3_3(config3_2, 3151 [](Status s, device::V3_3::HalStreamConfiguration) { 3152 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 3153 }); 3154 } else { 3155 ret = session->configureStreams(config3_2, 3156 [](Status s, HalStreamConfiguration) { 3157 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 3158 }); 3159 } 3160 ASSERT_TRUE(ret.isOk()); 3161 3162 free_camera_metadata(staticMeta); 3163 ret = session->close(); 3164 ASSERT_TRUE(ret.isOk()); 3165 } 3166 } 3167 3168 // Verify that all supported video + snapshot stream combinations can 3169 // be configured successfully. 3170 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { 3171 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3172 std::vector<AvailableStream> outputBlobStreams; 3173 std::vector<AvailableStream> outputVideoStreams; 3174 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight, 3175 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3176 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight, 3177 static_cast<int32_t>(PixelFormat::BLOB)}; 3178 3179 for (const auto& name : cameraDeviceNames) { 3180 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3181 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3182 continue; 3183 } else if (deviceVersion <= 0) { 3184 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3185 ADD_FAILURE(); 3186 return; 3187 } 3188 3189 camera_metadata_t* staticMeta; 3190 Return<void> ret; 3191 sp<ICameraDeviceSession> session; 3192 sp<device::V3_3::ICameraDeviceSession> session3_3; 3193 sp<device::V3_4::ICameraDeviceSession> session3_4; 3194 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 3195 castSession(session, deviceVersion, &session3_3, &session3_4); 3196 3197 outputBlobStreams.clear(); 3198 ASSERT_EQ(Status::OK, 3199 getAvailableOutputStreams(staticMeta, outputBlobStreams, 3200 &blobThreshold)); 3201 ASSERT_NE(0u, outputBlobStreams.size()); 3202 3203 outputVideoStreams.clear(); 3204 ASSERT_EQ(Status::OK, 3205 getAvailableOutputStreams(staticMeta, outputVideoStreams, 3206 &videoThreshold)); 3207 ASSERT_NE(0u, outputVideoStreams.size()); 3208 3209 int32_t streamId = 0; 3210 for (auto& blobIter : outputBlobStreams) { 3211 for (auto& videoIter : outputVideoStreams) { 3212 V3_2::Stream videoStream = {streamId++, 3213 StreamType::OUTPUT, 3214 static_cast<uint32_t>(videoIter.width), 3215 static_cast<uint32_t>(videoIter.height), 3216 static_cast<PixelFormat>(videoIter.format), 3217 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 3218 0, 3219 StreamRotation::ROTATION_0}; 3220 V3_2::Stream blobStream = {streamId++, 3221 StreamType::OUTPUT, 3222 static_cast<uint32_t>(blobIter.width), 3223 static_cast<uint32_t>(blobIter.height), 3224 static_cast<PixelFormat>(blobIter.format), 3225 GRALLOC1_CONSUMER_USAGE_CPU_READ, 3226 static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF), 3227 StreamRotation::ROTATION_0}; 3228 ::android::hardware::hidl_vec<V3_2::Stream> streams = {videoStream, blobStream}; 3229 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 3230 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 3231 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, 3232 &config3_2, &config3_4); 3233 if (session3_4 != nullptr) { 3234 ret = session3_4->configureStreams_3_4(config3_4, 3235 [](Status s, device::V3_4::HalStreamConfiguration halConfig) { 3236 ASSERT_EQ(Status::OK, s); 3237 ASSERT_EQ(2u, halConfig.streams.size()); 3238 }); 3239 } else if (session3_3 != nullptr) { 3240 ret = session3_3->configureStreams_3_3(config3_2, 3241 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 3242 ASSERT_EQ(Status::OK, s); 3243 ASSERT_EQ(2u, halConfig.streams.size()); 3244 }); 3245 } else { 3246 ret = session->configureStreams(config3_2, 3247 [](Status s, HalStreamConfiguration halConfig) { 3248 ASSERT_EQ(Status::OK, s); 3249 ASSERT_EQ(2u, halConfig.streams.size()); 3250 }); 3251 } 3252 ASSERT_TRUE(ret.isOk()); 3253 } 3254 } 3255 3256 free_camera_metadata(staticMeta); 3257 ret = session->close(); 3258 ASSERT_TRUE(ret.isOk()); 3259 } 3260 } 3261 3262 // Generate and verify a camera capture request 3263 TEST_F(CameraHidlTest, processCaptureRequestPreview) { 3264 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3265 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3266 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3267 uint64_t bufferId = 1; 3268 uint32_t frameNumber = 1; 3269 ::android::hardware::hidl_vec<uint8_t> settings; 3270 3271 for (const auto& name : cameraDeviceNames) { 3272 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3273 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3274 continue; 3275 } else if (deviceVersion <= 0) { 3276 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3277 ADD_FAILURE(); 3278 return; 3279 } 3280 3281 V3_2::Stream previewStream; 3282 HalStreamConfiguration halStreamConfig; 3283 sp<ICameraDeviceSession> session; 3284 bool supportsPartialResults = false; 3285 uint32_t partialResultCount = 0; 3286 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3287 &previewStream /*out*/, &halStreamConfig /*out*/, 3288 &supportsPartialResults /*out*/, 3289 &partialResultCount /*out*/); 3290 3291 std::shared_ptr<ResultMetadataQueue> resultQueue; 3292 auto resultQueueRet = 3293 session->getCaptureResultMetadataQueue( 3294 [&resultQueue](const auto& descriptor) { 3295 resultQueue = std::make_shared<ResultMetadataQueue>( 3296 descriptor); 3297 if (!resultQueue->isValid() || 3298 resultQueue->availableToWrite() <= 0) { 3299 ALOGE("%s: HAL returns empty result metadata fmq," 3300 " not use it", __func__); 3301 resultQueue = nullptr; 3302 // Don't use the queue onwards. 3303 } 3304 }); 3305 ASSERT_TRUE(resultQueueRet.isOk()); 3306 3307 InFlightRequest inflightReq = {1, false, supportsPartialResults, 3308 partialResultCount, resultQueue}; 3309 3310 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3311 Return<void> ret; 3312 ret = session->constructDefaultRequestSettings(reqTemplate, 3313 [&](auto status, const auto& req) { 3314 ASSERT_EQ(Status::OK, status); 3315 settings = req; 3316 }); 3317 ASSERT_TRUE(ret.isOk()); 3318 3319 hidl_handle buffer_handle; 3320 allocateGraphicBuffer(previewStream.width, previewStream.height, 3321 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3322 halStreamConfig.streams[0].consumerUsage), 3323 halStreamConfig.streams[0].overrideFormat, &buffer_handle); 3324 3325 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3326 bufferId, 3327 buffer_handle, 3328 BufferStatus::OK, 3329 nullptr, 3330 nullptr}; 3331 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; 3332 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, 3333 nullptr}; 3334 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3335 emptyInputBuffer, outputBuffers}; 3336 3337 { 3338 std::unique_lock<std::mutex> l(mLock); 3339 mInflightMap.clear(); 3340 mInflightMap.add(frameNumber, &inflightReq); 3341 } 3342 3343 Status status = Status::INTERNAL_ERROR; 3344 uint32_t numRequestProcessed = 0; 3345 hidl_vec<BufferCache> cachesToRemove; 3346 Return<void> returnStatus = session->processCaptureRequest( 3347 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3348 uint32_t n) { 3349 status = s; 3350 numRequestProcessed = n; 3351 }); 3352 ASSERT_TRUE(returnStatus.isOk()); 3353 ASSERT_EQ(Status::OK, status); 3354 ASSERT_EQ(numRequestProcessed, 1u); 3355 3356 { 3357 std::unique_lock<std::mutex> l(mLock); 3358 while (!inflightReq.errorCodeValid && 3359 ((0 < inflightReq.numBuffersLeft) || 3360 (!inflightReq.haveResultMetadata))) { 3361 auto timeout = std::chrono::system_clock::now() + 3362 std::chrono::seconds(kStreamBufferTimeoutSec); 3363 ASSERT_NE(std::cv_status::timeout, 3364 mResultCondition.wait_until(l, timeout)); 3365 } 3366 3367 ASSERT_FALSE(inflightReq.errorCodeValid); 3368 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3369 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); 3370 3371 request.frameNumber++; 3372 // Empty settings should be supported after the first call 3373 // for repeating requests. 3374 request.settings.setToExternal(nullptr, 0, true); 3375 // The buffer has been registered to HAL by bufferId, so per 3376 // API contract we should send a null handle for this buffer 3377 request.outputBuffers[0].buffer = nullptr; 3378 mInflightMap.clear(); 3379 inflightReq = {1, false, supportsPartialResults, partialResultCount, 3380 resultQueue}; 3381 mInflightMap.add(request.frameNumber, &inflightReq); 3382 } 3383 3384 returnStatus = session->processCaptureRequest( 3385 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3386 uint32_t n) { 3387 status = s; 3388 numRequestProcessed = n; 3389 }); 3390 ASSERT_TRUE(returnStatus.isOk()); 3391 ASSERT_EQ(Status::OK, status); 3392 ASSERT_EQ(numRequestProcessed, 1u); 3393 3394 { 3395 std::unique_lock<std::mutex> l(mLock); 3396 while (!inflightReq.errorCodeValid && 3397 ((0 < inflightReq.numBuffersLeft) || 3398 (!inflightReq.haveResultMetadata))) { 3399 auto timeout = std::chrono::system_clock::now() + 3400 std::chrono::seconds(kStreamBufferTimeoutSec); 3401 ASSERT_NE(std::cv_status::timeout, 3402 mResultCondition.wait_until(l, timeout)); 3403 } 3404 3405 ASSERT_FALSE(inflightReq.errorCodeValid); 3406 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3407 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); 3408 } 3409 3410 ret = session->close(); 3411 ASSERT_TRUE(ret.isOk()); 3412 } 3413 } 3414 3415 // Generate and verify a multi-camera capture request 3416 TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) { 3417 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3418 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3419 static_cast<int32_t>(PixelFormat::YCBCR_420_888)}; 3420 uint64_t bufferId = 1; 3421 uint32_t frameNumber = 1; 3422 ::android::hardware::hidl_vec<uint8_t> settings; 3423 ::android::hardware::hidl_vec<uint8_t> emptySettings; 3424 hidl_string invalidPhysicalId = "-1"; 3425 3426 for (const auto& name : cameraDeviceNames) { 3427 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3428 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) { 3429 continue; 3430 } 3431 std::string version, deviceId; 3432 ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); 3433 camera_metadata_t* staticMeta; 3434 Return<void> ret; 3435 sp<ICameraDeviceSession> session; 3436 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 3437 3438 Status rc = isLogicalMultiCamera(staticMeta); 3439 if (Status::METHOD_NOT_SUPPORTED == rc) { 3440 free_camera_metadata(staticMeta); 3441 ret = session->close(); 3442 ASSERT_TRUE(ret.isOk()); 3443 continue; 3444 } 3445 std::unordered_set<std::string> physicalIds; 3446 rc = getPhysicalCameraIds(staticMeta, &physicalIds); 3447 ASSERT_TRUE(Status::OK == rc); 3448 ASSERT_TRUE(physicalIds.size() > 1); 3449 3450 std::unordered_set<int32_t> physicalRequestKeyIDs; 3451 rc = getSupportedKeys(staticMeta, 3452 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs); 3453 ASSERT_TRUE(Status::OK == rc); 3454 if (physicalRequestKeyIDs.empty()) { 3455 free_camera_metadata(staticMeta); 3456 ret = session->close(); 3457 ASSERT_TRUE(ret.isOk()); 3458 // The logical camera doesn't support any individual physical requests. 3459 continue; 3460 } 3461 3462 android::hardware::camera::common::V1_0::helper::CameraMetadata defaultPreviewSettings; 3463 android::hardware::camera::common::V1_0::helper::CameraMetadata filteredSettings; 3464 constructFilteredSettings(session, physicalRequestKeyIDs, RequestTemplate::PREVIEW, 3465 &defaultPreviewSettings, &filteredSettings); 3466 if (filteredSettings.isEmpty()) { 3467 // No physical device settings in default request. 3468 free_camera_metadata(staticMeta); 3469 ret = session->close(); 3470 ASSERT_TRUE(ret.isOk()); 3471 continue; 3472 } 3473 3474 const camera_metadata_t *settingsBuffer = defaultPreviewSettings.getAndLock(); 3475 settings.setToExternal( 3476 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (settingsBuffer)), 3477 get_camera_metadata_size(settingsBuffer)); 3478 3479 free_camera_metadata(staticMeta); 3480 ret = session->close(); 3481 ASSERT_TRUE(ret.isOk()); 3482 3483 // Leave only 2 physical devices in the id set. 3484 auto it = physicalIds.begin(); 3485 string physicalDeviceId = *it; it++; 3486 physicalIds.erase(++it, physicalIds.end()); 3487 ASSERT_EQ(physicalIds.size(), 2u); 3488 3489 V3_4::HalStreamConfiguration halStreamConfig; 3490 bool supportsPartialResults = false; 3491 uint32_t partialResultCount = 0; 3492 V3_2::Stream previewStream; 3493 sp<device::V3_4::ICameraDeviceSession> session3_4; 3494 configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds, 3495 &session3_4, &previewStream, &halStreamConfig /*out*/, 3496 &supportsPartialResults /*out*/, &partialResultCount /*out*/); 3497 ASSERT_NE(session3_4, nullptr); 3498 3499 std::shared_ptr<ResultMetadataQueue> resultQueue; 3500 auto resultQueueRet = 3501 session3_4->getCaptureResultMetadataQueue( 3502 [&resultQueue](const auto& descriptor) { 3503 resultQueue = std::make_shared<ResultMetadataQueue>( 3504 descriptor); 3505 if (!resultQueue->isValid() || 3506 resultQueue->availableToWrite() <= 0) { 3507 ALOGE("%s: HAL returns empty result metadata fmq," 3508 " not use it", __func__); 3509 resultQueue = nullptr; 3510 // Don't use the queue onwards. 3511 } 3512 }); 3513 ASSERT_TRUE(resultQueueRet.isOk()); 3514 3515 InFlightRequest inflightReq = {static_cast<ssize_t> (halStreamConfig.streams.size()), false, 3516 supportsPartialResults, partialResultCount, resultQueue}; 3517 3518 std::vector<hidl_handle> graphicBuffers; 3519 graphicBuffers.reserve(halStreamConfig.streams.size()); 3520 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers; 3521 outputBuffers.resize(halStreamConfig.streams.size()); 3522 size_t k = 0; 3523 for (const auto& halStream : halStreamConfig.streams) { 3524 hidl_handle buffer_handle; 3525 allocateGraphicBuffer(previewStream.width, previewStream.height, 3526 android_convertGralloc1To0Usage(halStream.v3_3.v3_2.producerUsage, 3527 halStream.v3_3.v3_2.consumerUsage), 3528 halStream.v3_3.v3_2.overrideFormat, &buffer_handle); 3529 graphicBuffers.push_back(buffer_handle); 3530 outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId, buffer_handle, 3531 BufferStatus::OK, nullptr, nullptr}; 3532 bufferId++; 3533 k++; 3534 } 3535 hidl_vec<V3_4::PhysicalCameraSetting> camSettings(1); 3536 const camera_metadata_t *filteredSettingsBuffer = filteredSettings.getAndLock(); 3537 camSettings[0].settings.setToExternal( 3538 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> ( 3539 filteredSettingsBuffer)), 3540 get_camera_metadata_size(filteredSettingsBuffer)); 3541 camSettings[0].fmqSettingsSize = 0; 3542 camSettings[0].physicalCameraId = physicalDeviceId; 3543 3544 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; 3545 V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings, 3546 emptyInputBuffer, outputBuffers}, camSettings}; 3547 3548 { 3549 std::unique_lock<std::mutex> l(mLock); 3550 mInflightMap.clear(); 3551 mInflightMap.add(frameNumber, &inflightReq); 3552 } 3553 3554 Status stat = Status::INTERNAL_ERROR; 3555 uint32_t numRequestProcessed = 0; 3556 hidl_vec<BufferCache> cachesToRemove; 3557 Return<void> returnStatus = session3_4->processCaptureRequest_3_4( 3558 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) { 3559 stat = s; 3560 numRequestProcessed = n; 3561 }); 3562 ASSERT_TRUE(returnStatus.isOk()); 3563 ASSERT_EQ(Status::OK, stat); 3564 ASSERT_EQ(numRequestProcessed, 1u); 3565 3566 { 3567 std::unique_lock<std::mutex> l(mLock); 3568 while (!inflightReq.errorCodeValid && 3569 ((0 < inflightReq.numBuffersLeft) || 3570 (!inflightReq.haveResultMetadata))) { 3571 auto timeout = std::chrono::system_clock::now() + 3572 std::chrono::seconds(kStreamBufferTimeoutSec); 3573 ASSERT_NE(std::cv_status::timeout, 3574 mResultCondition.wait_until(l, timeout)); 3575 } 3576 3577 ASSERT_FALSE(inflightReq.errorCodeValid); 3578 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3579 3580 request.v3_2.frameNumber++; 3581 // Empty settings should be supported after the first call 3582 // for repeating requests. 3583 request.v3_2.settings.setToExternal(nullptr, 0, true); 3584 request.physicalCameraSettings[0].settings.setToExternal(nullptr, 0, true); 3585 // The buffer has been registered to HAL by bufferId, so per 3586 // API contract we should send a null handle for this buffer 3587 request.v3_2.outputBuffers[0].buffer = nullptr; 3588 mInflightMap.clear(); 3589 inflightReq = {static_cast<ssize_t> (physicalIds.size()), false, 3590 supportsPartialResults, partialResultCount, resultQueue}; 3591 mInflightMap.add(request.v3_2.frameNumber, &inflightReq); 3592 } 3593 3594 returnStatus = session3_4->processCaptureRequest_3_4( 3595 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) { 3596 stat = s; 3597 numRequestProcessed = n; 3598 }); 3599 ASSERT_TRUE(returnStatus.isOk()); 3600 ASSERT_EQ(Status::OK, stat); 3601 ASSERT_EQ(numRequestProcessed, 1u); 3602 3603 { 3604 std::unique_lock<std::mutex> l(mLock); 3605 while (!inflightReq.errorCodeValid && 3606 ((0 < inflightReq.numBuffersLeft) || 3607 (!inflightReq.haveResultMetadata))) { 3608 auto timeout = std::chrono::system_clock::now() + 3609 std::chrono::seconds(kStreamBufferTimeoutSec); 3610 ASSERT_NE(std::cv_status::timeout, 3611 mResultCondition.wait_until(l, timeout)); 3612 } 3613 3614 ASSERT_FALSE(inflightReq.errorCodeValid); 3615 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3616 } 3617 3618 // Invalid physical camera id should fail process requests 3619 frameNumber++; 3620 camSettings[0].physicalCameraId = invalidPhysicalId; 3621 camSettings[0].settings = settings; 3622 request = {{frameNumber, 0 /* fmqSettingsSize */, settings, 3623 emptyInputBuffer, outputBuffers}, camSettings}; 3624 returnStatus = session3_4->processCaptureRequest_3_4( 3625 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) { 3626 stat = s; 3627 numRequestProcessed = n; 3628 }); 3629 ASSERT_TRUE(returnStatus.isOk()); 3630 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat); 3631 3632 defaultPreviewSettings.unlock(settingsBuffer); 3633 filteredSettings.unlock(filteredSettingsBuffer); 3634 ret = session3_4->close(); 3635 ASSERT_TRUE(ret.isOk()); 3636 } 3637 } 3638 3639 // Generate and verify a burst containing alternating sensor sensitivity values 3640 TEST_F(CameraHidlTest, processCaptureRequestBurstISO) { 3641 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3642 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3643 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3644 uint64_t bufferId = 1; 3645 uint32_t frameNumber = 1; 3646 ::android::hardware::hidl_vec<uint8_t> settings; 3647 3648 for (const auto& name : cameraDeviceNames) { 3649 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3650 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3651 continue; 3652 } else if (deviceVersion <= 0) { 3653 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3654 ADD_FAILURE(); 3655 return; 3656 } 3657 camera_metadata_t* staticMetaBuffer; 3658 Return<void> ret; 3659 sp<ICameraDeviceSession> session; 3660 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); 3661 ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta( 3662 staticMetaBuffer); 3663 3664 camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL); 3665 ASSERT_TRUE(0 < hwLevel.count); 3666 if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0] || 3667 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL == hwLevel.data.u8[0]) { 3668 //Limited/External devices can skip this test 3669 ret = session->close(); 3670 ASSERT_TRUE(ret.isOk()); 3671 continue; 3672 } 3673 3674 camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE); 3675 ASSERT_EQ(isoRange.count, 2u); 3676 3677 ret = session->close(); 3678 ASSERT_TRUE(ret.isOk()); 3679 3680 bool supportsPartialResults = false; 3681 uint32_t partialResultCount = 0; 3682 V3_2::Stream previewStream; 3683 HalStreamConfiguration halStreamConfig; 3684 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, 3685 &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/, 3686 &supportsPartialResults /*out*/, &partialResultCount /*out*/); 3687 std::shared_ptr<ResultMetadataQueue> resultQueue; 3688 3689 auto resultQueueRet = session->getCaptureResultMetadataQueue( 3690 [&resultQueue](const auto& descriptor) { 3691 resultQueue = std::make_shared<ResultMetadataQueue>(descriptor); 3692 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) { 3693 ALOGE("%s: HAL returns empty result metadata fmq," 3694 " not use it", __func__); 3695 resultQueue = nullptr; 3696 // Don't use the queue onwards. 3697 } 3698 }); 3699 ASSERT_TRUE(resultQueueRet.isOk()); 3700 ASSERT_NE(nullptr, resultQueue); 3701 3702 ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW, 3703 [&](auto status, const auto& req) { 3704 ASSERT_EQ(Status::OK, status); 3705 settings = req; }); 3706 ASSERT_TRUE(ret.isOk()); 3707 3708 ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta; 3709 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr}; 3710 hidl_handle buffers[kBurstFrameCount]; 3711 StreamBuffer outputBuffers[kBurstFrameCount]; 3712 CaptureRequest requests[kBurstFrameCount]; 3713 InFlightRequest inflightReqs[kBurstFrameCount]; 3714 int32_t isoValues[kBurstFrameCount]; 3715 hidl_vec<uint8_t> requestSettings[kBurstFrameCount]; 3716 for (uint32_t i = 0; i < kBurstFrameCount; i++) { 3717 std::unique_lock<std::mutex> l(mLock); 3718 3719 isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1]; 3720 allocateGraphicBuffer(previewStream.width, previewStream.height, 3721 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3722 halStreamConfig.streams[0].consumerUsage), 3723 halStreamConfig.streams[0].overrideFormat, &buffers[i]); 3724 3725 outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i, 3726 buffers[i], BufferStatus::OK, nullptr, nullptr}; 3727 requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data())); 3728 3729 // Disable all 3A routines 3730 uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF); 3731 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1)); 3732 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i], 3733 1)); 3734 camera_metadata_t *metaBuffer = requestMeta.release(); 3735 requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer), 3736 get_camera_metadata_size(metaBuffer), true); 3737 3738 requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i], 3739 emptyInputBuffer, {outputBuffers[i]}}; 3740 3741 inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount, resultQueue}; 3742 mInflightMap.add(frameNumber + i, &inflightReqs[i]); 3743 } 3744 3745 Status status = Status::INTERNAL_ERROR; 3746 uint32_t numRequestProcessed = 0; 3747 hidl_vec<BufferCache> cachesToRemove; 3748 hidl_vec<CaptureRequest> burstRequest; 3749 burstRequest.setToExternal(requests, kBurstFrameCount); 3750 Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove, 3751 [&status, &numRequestProcessed] (auto s, uint32_t n) { 3752 status = s; 3753 numRequestProcessed = n; 3754 }); 3755 ASSERT_TRUE(returnStatus.isOk()); 3756 ASSERT_EQ(Status::OK, status); 3757 ASSERT_EQ(numRequestProcessed, kBurstFrameCount); 3758 3759 for (size_t i = 0; i < kBurstFrameCount; i++) { 3760 std::unique_lock<std::mutex> l(mLock); 3761 while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) || 3762 (!inflightReqs[i].haveResultMetadata))) { 3763 auto timeout = std::chrono::system_clock::now() + 3764 std::chrono::seconds(kStreamBufferTimeoutSec); 3765 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); 3766 } 3767 3768 ASSERT_FALSE(inflightReqs[i].errorCodeValid); 3769 ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u); 3770 ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId); 3771 ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty()); 3772 ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY)); 3773 camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find( 3774 ANDROID_SENSOR_SENSITIVITY); 3775 ASSERT_TRUE(isoResult.data.i32[0] == isoValues[i]); 3776 } 3777 3778 ret = session->close(); 3779 ASSERT_TRUE(ret.isOk()); 3780 } 3781 } 3782 3783 // Test whether an incorrect capture request with missing settings will 3784 // be reported correctly. 3785 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) { 3786 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3787 std::vector<AvailableStream> outputPreviewStreams; 3788 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3789 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3790 uint64_t bufferId = 1; 3791 uint32_t frameNumber = 1; 3792 ::android::hardware::hidl_vec<uint8_t> settings; 3793 3794 for (const auto& name : cameraDeviceNames) { 3795 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3796 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3797 continue; 3798 } else if (deviceVersion <= 0) { 3799 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3800 ADD_FAILURE(); 3801 return; 3802 } 3803 3804 V3_2::Stream previewStream; 3805 HalStreamConfiguration halStreamConfig; 3806 sp<ICameraDeviceSession> session; 3807 bool supportsPartialResults = false; 3808 uint32_t partialResultCount = 0; 3809 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3810 &previewStream /*out*/, &halStreamConfig /*out*/, 3811 &supportsPartialResults /*out*/, 3812 &partialResultCount /*out*/); 3813 3814 hidl_handle buffer_handle; 3815 allocateGraphicBuffer(previewStream.width, previewStream.height, 3816 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3817 halStreamConfig.streams[0].consumerUsage), 3818 halStreamConfig.streams[0].overrideFormat, &buffer_handle); 3819 3820 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3821 bufferId, 3822 buffer_handle, 3823 BufferStatus::OK, 3824 nullptr, 3825 nullptr}; 3826 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; 3827 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, 3828 nullptr}; 3829 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3830 emptyInputBuffer, outputBuffers}; 3831 3832 // Settings were not correctly initialized, we should fail here 3833 Status status = Status::OK; 3834 uint32_t numRequestProcessed = 0; 3835 hidl_vec<BufferCache> cachesToRemove; 3836 Return<void> ret = session->processCaptureRequest( 3837 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3838 uint32_t n) { 3839 status = s; 3840 numRequestProcessed = n; 3841 }); 3842 ASSERT_TRUE(ret.isOk()); 3843 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); 3844 ASSERT_EQ(numRequestProcessed, 0u); 3845 3846 ret = session->close(); 3847 ASSERT_TRUE(ret.isOk()); 3848 } 3849 } 3850 3851 // Check whether an invalid capture request with missing output buffers 3852 // will be reported correctly. 3853 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) { 3854 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3855 std::vector<AvailableStream> outputBlobStreams; 3856 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3857 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3858 uint32_t frameNumber = 1; 3859 ::android::hardware::hidl_vec<uint8_t> settings; 3860 3861 for (const auto& name : cameraDeviceNames) { 3862 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3863 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3864 continue; 3865 } else if (deviceVersion <= 0) { 3866 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3867 ADD_FAILURE(); 3868 return; 3869 } 3870 3871 V3_2::Stream previewStream; 3872 HalStreamConfiguration halStreamConfig; 3873 sp<ICameraDeviceSession> session; 3874 bool supportsPartialResults = false; 3875 uint32_t partialResultCount = 0; 3876 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3877 &previewStream /*out*/, &halStreamConfig /*out*/, 3878 &supportsPartialResults /*out*/, 3879 &partialResultCount /*out*/); 3880 3881 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3882 Return<void> ret; 3883 ret = session->constructDefaultRequestSettings(reqTemplate, 3884 [&](auto status, const auto& req) { 3885 ASSERT_EQ(Status::OK, status); 3886 settings = req; 3887 }); 3888 ASSERT_TRUE(ret.isOk()); 3889 3890 ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers; 3891 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, 3892 nullptr}; 3893 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3894 emptyInputBuffer, emptyOutputBuffers}; 3895 3896 // Output buffers are missing, we should fail here 3897 Status status = Status::OK; 3898 uint32_t numRequestProcessed = 0; 3899 hidl_vec<BufferCache> cachesToRemove; 3900 ret = session->processCaptureRequest( 3901 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3902 uint32_t n) { 3903 status = s; 3904 numRequestProcessed = n; 3905 }); 3906 ASSERT_TRUE(ret.isOk()); 3907 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); 3908 ASSERT_EQ(numRequestProcessed, 0u); 3909 3910 ret = session->close(); 3911 ASSERT_TRUE(ret.isOk()); 3912 } 3913 } 3914 3915 // Generate, trigger and flush a preview request 3916 TEST_F(CameraHidlTest, flushPreviewRequest) { 3917 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3918 std::vector<AvailableStream> outputPreviewStreams; 3919 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3920 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3921 uint64_t bufferId = 1; 3922 uint32_t frameNumber = 1; 3923 ::android::hardware::hidl_vec<uint8_t> settings; 3924 3925 for (const auto& name : cameraDeviceNames) { 3926 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3927 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3928 continue; 3929 } else if (deviceVersion <= 0) { 3930 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3931 ADD_FAILURE(); 3932 return; 3933 } 3934 3935 V3_2::Stream previewStream; 3936 HalStreamConfiguration halStreamConfig; 3937 sp<ICameraDeviceSession> session; 3938 bool supportsPartialResults = false; 3939 uint32_t partialResultCount = 0; 3940 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3941 &previewStream /*out*/, &halStreamConfig /*out*/, 3942 &supportsPartialResults /*out*/, 3943 &partialResultCount /*out*/); 3944 3945 std::shared_ptr<ResultMetadataQueue> resultQueue; 3946 auto resultQueueRet = 3947 session->getCaptureResultMetadataQueue( 3948 [&resultQueue](const auto& descriptor) { 3949 resultQueue = std::make_shared<ResultMetadataQueue>( 3950 descriptor); 3951 if (!resultQueue->isValid() || 3952 resultQueue->availableToWrite() <= 0) { 3953 ALOGE("%s: HAL returns empty result metadata fmq," 3954 " not use it", __func__); 3955 resultQueue = nullptr; 3956 // Don't use the queue onwards. 3957 } 3958 }); 3959 ASSERT_TRUE(resultQueueRet.isOk()); 3960 3961 InFlightRequest inflightReq = {1, false, supportsPartialResults, 3962 partialResultCount, resultQueue}; 3963 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3964 Return<void> ret; 3965 ret = session->constructDefaultRequestSettings(reqTemplate, 3966 [&](auto status, const auto& req) { 3967 ASSERT_EQ(Status::OK, status); 3968 settings = req; 3969 }); 3970 ASSERT_TRUE(ret.isOk()); 3971 3972 hidl_handle buffer_handle; 3973 allocateGraphicBuffer(previewStream.width, previewStream.height, 3974 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3975 halStreamConfig.streams[0].consumerUsage), 3976 halStreamConfig.streams[0].overrideFormat, &buffer_handle); 3977 3978 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3979 bufferId, 3980 buffer_handle, 3981 BufferStatus::OK, 3982 nullptr, 3983 nullptr}; 3984 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; 3985 const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, 3986 BufferStatus::ERROR, nullptr, nullptr}; 3987 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3988 emptyInputBuffer, outputBuffers}; 3989 3990 { 3991 std::unique_lock<std::mutex> l(mLock); 3992 mInflightMap.clear(); 3993 mInflightMap.add(frameNumber, &inflightReq); 3994 } 3995 3996 Status status = Status::INTERNAL_ERROR; 3997 uint32_t numRequestProcessed = 0; 3998 hidl_vec<BufferCache> cachesToRemove; 3999 ret = session->processCaptureRequest( 4000 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 4001 uint32_t n) { 4002 status = s; 4003 numRequestProcessed = n; 4004 }); 4005 4006 ASSERT_TRUE(ret.isOk()); 4007 ASSERT_EQ(Status::OK, status); 4008 ASSERT_EQ(numRequestProcessed, 1u); 4009 // Flush before waiting for request to complete. 4010 Return<Status> returnStatus = session->flush(); 4011 ASSERT_TRUE(returnStatus.isOk()); 4012 ASSERT_EQ(Status::OK, returnStatus); 4013 4014 { 4015 std::unique_lock<std::mutex> l(mLock); 4016 while (!inflightReq.errorCodeValid && 4017 ((0 < inflightReq.numBuffersLeft) || 4018 (!inflightReq.haveResultMetadata))) { 4019 auto timeout = std::chrono::system_clock::now() + 4020 std::chrono::seconds(kStreamBufferTimeoutSec); 4021 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, 4022 timeout)); 4023 } 4024 4025 if (!inflightReq.errorCodeValid) { 4026 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 4027 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); 4028 } else { 4029 switch (inflightReq.errorCode) { 4030 case ErrorCode::ERROR_REQUEST: 4031 case ErrorCode::ERROR_RESULT: 4032 case ErrorCode::ERROR_BUFFER: 4033 // Expected 4034 break; 4035 case ErrorCode::ERROR_DEVICE: 4036 default: 4037 FAIL() << "Unexpected error:" 4038 << static_cast<uint32_t>(inflightReq.errorCode); 4039 } 4040 } 4041 4042 ret = session->close(); 4043 ASSERT_TRUE(ret.isOk()); 4044 } 4045 } 4046 } 4047 4048 // Verify that camera flushes correctly without any pending requests. 4049 TEST_F(CameraHidlTest, flushEmpty) { 4050 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 4051 std::vector<AvailableStream> outputPreviewStreams; 4052 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 4053 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 4054 4055 for (const auto& name : cameraDeviceNames) { 4056 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 4057 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 4058 continue; 4059 } else if (deviceVersion <= 0) { 4060 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 4061 ADD_FAILURE(); 4062 return; 4063 } 4064 4065 V3_2::Stream previewStream; 4066 HalStreamConfiguration halStreamConfig; 4067 sp<ICameraDeviceSession> session; 4068 bool supportsPartialResults = false; 4069 uint32_t partialResultCount = 0; 4070 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 4071 &previewStream /*out*/, &halStreamConfig /*out*/, 4072 &supportsPartialResults /*out*/, 4073 &partialResultCount /*out*/); 4074 4075 Return<Status> returnStatus = session->flush(); 4076 ASSERT_TRUE(returnStatus.isOk()); 4077 ASSERT_EQ(Status::OK, returnStatus); 4078 4079 { 4080 std::unique_lock<std::mutex> l(mLock); 4081 auto timeout = std::chrono::system_clock::now() + 4082 std::chrono::milliseconds(kEmptyFlushTimeoutMSec); 4083 ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); 4084 } 4085 4086 Return<void> ret = session->close(); 4087 ASSERT_TRUE(ret.isOk()); 4088 } 4089 } 4090 4091 // Retrieve all valid output stream resolutions from the camera 4092 // static characteristics. 4093 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta, 4094 std::vector<AvailableStream> &outputStreams, 4095 const AvailableStream *threshold) { 4096 if (nullptr == staticMeta) { 4097 return Status::ILLEGAL_ARGUMENT; 4098 } 4099 4100 camera_metadata_ro_entry entry; 4101 int rc = find_camera_metadata_ro_entry(staticMeta, 4102 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry); 4103 if ((0 != rc) || (0 != (entry.count % 4))) { 4104 return Status::ILLEGAL_ARGUMENT; 4105 } 4106 4107 for (size_t i = 0; i < entry.count; i+=4) { 4108 if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT == 4109 entry.data.i32[i + 3]) { 4110 if(nullptr == threshold) { 4111 AvailableStream s = {entry.data.i32[i+1], 4112 entry.data.i32[i+2], entry.data.i32[i]}; 4113 outputStreams.push_back(s); 4114 } else { 4115 if ((threshold->format == entry.data.i32[i]) && 4116 (threshold->width >= entry.data.i32[i+1]) && 4117 (threshold->height >= entry.data.i32[i+2])) { 4118 AvailableStream s = {entry.data.i32[i+1], 4119 entry.data.i32[i+2], threshold->format}; 4120 outputStreams.push_back(s); 4121 } 4122 } 4123 } 4124 4125 } 4126 4127 return Status::OK; 4128 } 4129 4130 // Check if the camera device has logical multi-camera capability. 4131 Status CameraHidlTest::isLogicalMultiCamera(camera_metadata_t *staticMeta) { 4132 Status ret = Status::METHOD_NOT_SUPPORTED; 4133 if (nullptr == staticMeta) { 4134 return Status::ILLEGAL_ARGUMENT; 4135 } 4136 4137 camera_metadata_ro_entry entry; 4138 int rc = find_camera_metadata_ro_entry(staticMeta, 4139 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 4140 if (0 != rc) { 4141 return Status::ILLEGAL_ARGUMENT; 4142 } 4143 4144 for (size_t i = 0; i < entry.count; i++) { 4145 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA == entry.data.u8[i]) { 4146 ret = Status::OK; 4147 break; 4148 } 4149 } 4150 4151 return ret; 4152 } 4153 4154 // Generate a list of physical camera ids backing a logical multi-camera. 4155 Status CameraHidlTest::getPhysicalCameraIds(camera_metadata_t *staticMeta, 4156 std::unordered_set<std::string> *physicalIds) { 4157 if ((nullptr == staticMeta) || (nullptr == physicalIds)) { 4158 return Status::ILLEGAL_ARGUMENT; 4159 } 4160 4161 camera_metadata_ro_entry entry; 4162 int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS, 4163 &entry); 4164 if (0 != rc) { 4165 return Status::ILLEGAL_ARGUMENT; 4166 } 4167 4168 const uint8_t* ids = entry.data.u8; 4169 size_t start = 0; 4170 for (size_t i = 0; i < entry.count; i++) { 4171 if (ids[i] == '\0') { 4172 if (start != i) { 4173 std::string currentId(reinterpret_cast<const char *> (ids + start)); 4174 physicalIds->emplace(currentId); 4175 } 4176 start = i + 1; 4177 } 4178 } 4179 4180 return Status::OK; 4181 } 4182 4183 // Generate a set of suported camera key ids. 4184 Status CameraHidlTest::getSupportedKeys(camera_metadata_t *staticMeta, 4185 uint32_t tagId, std::unordered_set<int32_t> *requestIDs) { 4186 if ((nullptr == staticMeta) || (nullptr == requestIDs)) { 4187 return Status::ILLEGAL_ARGUMENT; 4188 } 4189 4190 camera_metadata_ro_entry entry; 4191 int rc = find_camera_metadata_ro_entry(staticMeta, tagId, &entry); 4192 if ((0 != rc) || (entry.count == 0)) { 4193 return Status::OK; 4194 } 4195 4196 requestIDs->insert(entry.data.i32, entry.data.i32 + entry.count); 4197 4198 return Status::OK; 4199 } 4200 4201 void CameraHidlTest::constructFilteredSettings(const sp<ICameraDeviceSession>& session, 4202 const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate, 4203 android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings, 4204 android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings) { 4205 ASSERT_NE(defaultSettings, nullptr); 4206 ASSERT_NE(filteredSettings, nullptr); 4207 4208 auto ret = session->constructDefaultRequestSettings(reqTemplate, 4209 [&defaultSettings] (auto status, const auto& req) mutable { 4210 ASSERT_EQ(Status::OK, status); 4211 4212 const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> ( 4213 req.data()); 4214 size_t expectedSize = req.size(); 4215 int result = validate_camera_metadata_structure(metadata, &expectedSize); 4216 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 4217 4218 size_t entryCount = get_camera_metadata_entry_count(metadata); 4219 ASSERT_GT(entryCount, 0u); 4220 *defaultSettings = metadata; 4221 }); 4222 ASSERT_TRUE(ret.isOk()); 4223 const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings = 4224 *defaultSettings; 4225 for (const auto& keyIt : availableKeys) { 4226 camera_metadata_ro_entry entry = constSettings.find(keyIt); 4227 if (entry.count > 0) { 4228 filteredSettings->update(entry); 4229 } 4230 } 4231 } 4232 4233 // Check if constrained mode is supported by using the static 4234 // camera characteristics. 4235 Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) { 4236 Status ret = Status::METHOD_NOT_SUPPORTED; 4237 if (nullptr == staticMeta) { 4238 return Status::ILLEGAL_ARGUMENT; 4239 } 4240 4241 camera_metadata_ro_entry entry; 4242 int rc = find_camera_metadata_ro_entry(staticMeta, 4243 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 4244 if (0 != rc) { 4245 return Status::ILLEGAL_ARGUMENT; 4246 } 4247 4248 for (size_t i = 0; i < entry.count; i++) { 4249 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO == 4250 entry.data.u8[i]) { 4251 ret = Status::OK; 4252 break; 4253 } 4254 } 4255 4256 return ret; 4257 } 4258 4259 // Pick the largest supported HFR mode from the static camera 4260 // characteristics. 4261 Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta, 4262 AvailableStream &hfrStream) { 4263 if (nullptr == staticMeta) { 4264 return Status::ILLEGAL_ARGUMENT; 4265 } 4266 4267 camera_metadata_ro_entry entry; 4268 int rc = find_camera_metadata_ro_entry(staticMeta, 4269 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry); 4270 if (0 != rc) { 4271 return Status::METHOD_NOT_SUPPORTED; 4272 } else if (0 != (entry.count % 5)) { 4273 return Status::ILLEGAL_ARGUMENT; 4274 } 4275 4276 hfrStream = {0, 0, 4277 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 4278 for (size_t i = 0; i < entry.count; i+=5) { 4279 int32_t w = entry.data.i32[i]; 4280 int32_t h = entry.data.i32[i+1]; 4281 if ((hfrStream.width * hfrStream.height) < (w *h)) { 4282 hfrStream.width = w; 4283 hfrStream.height = h; 4284 } 4285 } 4286 4287 return Status::OK; 4288 } 4289 4290 // Check whether ZSL is available using the static camera 4291 // characteristics. 4292 Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) { 4293 Status ret = Status::METHOD_NOT_SUPPORTED; 4294 if (nullptr == staticMeta) { 4295 return Status::ILLEGAL_ARGUMENT; 4296 } 4297 4298 camera_metadata_ro_entry entry; 4299 int rc = find_camera_metadata_ro_entry(staticMeta, 4300 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 4301 if (0 != rc) { 4302 return Status::ILLEGAL_ARGUMENT; 4303 } 4304 4305 for (size_t i = 0; i < entry.count; i++) { 4306 if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING == 4307 entry.data.u8[i]) || 4308 (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING == 4309 entry.data.u8[i]) ){ 4310 ret = Status::OK; 4311 break; 4312 } 4313 } 4314 4315 return ret; 4316 } 4317 4318 // Retrieve the reprocess input-output format map from the static 4319 // camera characteristics. 4320 Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta, 4321 std::vector<AvailableZSLInputOutput> &inputOutputMap) { 4322 if (nullptr == staticMeta) { 4323 return Status::ILLEGAL_ARGUMENT; 4324 } 4325 4326 camera_metadata_ro_entry entry; 4327 int rc = find_camera_metadata_ro_entry(staticMeta, 4328 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry); 4329 if ((0 != rc) || (0 >= entry.count)) { 4330 return Status::ILLEGAL_ARGUMENT; 4331 } 4332 4333 const int32_t* contents = &entry.data.i32[0]; 4334 for (size_t i = 0; i < entry.count; ) { 4335 int32_t inputFormat = contents[i++]; 4336 int32_t length = contents[i++]; 4337 for (int32_t j = 0; j < length; j++) { 4338 int32_t outputFormat = contents[i+j]; 4339 AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat}; 4340 inputOutputMap.push_back(zslEntry); 4341 } 4342 i += length; 4343 } 4344 4345 return Status::OK; 4346 } 4347 4348 // Search for the largest stream size for a given format. 4349 Status CameraHidlTest::findLargestSize( 4350 const std::vector<AvailableStream> &streamSizes, int32_t format, 4351 AvailableStream &result) { 4352 result = {0, 0, 0}; 4353 for (auto &iter : streamSizes) { 4354 if (format == iter.format) { 4355 if ((result.width * result.height) < (iter.width * iter.height)) { 4356 result = iter; 4357 } 4358 } 4359 } 4360 4361 return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT; 4362 } 4363 4364 // Check whether the camera device supports specific focus mode. 4365 Status CameraHidlTest::isAutoFocusModeAvailable( 4366 CameraParameters &cameraParams, 4367 const char *mode) { 4368 ::android::String8 focusModes(cameraParams.get( 4369 CameraParameters::KEY_SUPPORTED_FOCUS_MODES)); 4370 if (focusModes.contains(mode)) { 4371 return Status::OK; 4372 } 4373 4374 return Status::METHOD_NOT_SUPPORTED; 4375 } 4376 4377 void CameraHidlTest::createStreamConfiguration( 4378 const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2, 4379 StreamConfigurationMode configMode, 4380 ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/, 4381 ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/) { 4382 ASSERT_NE(nullptr, config3_2); 4383 ASSERT_NE(nullptr, config3_4); 4384 4385 ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(streams3_2.size()); 4386 size_t idx = 0; 4387 for (auto& stream3_2 : streams3_2) { 4388 V3_4::Stream stream; 4389 stream.v3_2 = stream3_2; 4390 streams3_4[idx++] = stream; 4391 } 4392 *config3_4 = {streams3_4, configMode, {}}; 4393 *config3_2 = {streams3_2, configMode}; 4394 } 4395 4396 // Configure multiple preview streams using different physical ids. 4397 void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, 4398 sp<ICameraProvider> provider, 4399 const AvailableStream *previewThreshold, 4400 const std::unordered_set<std::string>& physicalIds, 4401 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/, 4402 V3_2::Stream *previewStream /*out*/, 4403 device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/, 4404 bool *supportsPartialResults /*out*/, 4405 uint32_t *partialResultCount /*out*/) { 4406 ASSERT_NE(nullptr, session3_4); 4407 ASSERT_NE(nullptr, halStreamConfig); 4408 ASSERT_NE(nullptr, previewStream); 4409 ASSERT_NE(nullptr, supportsPartialResults); 4410 ASSERT_NE(nullptr, partialResultCount); 4411 ASSERT_FALSE(physicalIds.empty()); 4412 4413 std::vector<AvailableStream> outputPreviewStreams; 4414 ::android::sp<ICameraDevice> device3_x; 4415 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 4416 Return<void> ret; 4417 ret = provider->getCameraDeviceInterface_V3_x( 4418 name, 4419 [&](auto status, const auto& device) { 4420 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 4421 (int)status); 4422 ASSERT_EQ(Status::OK, status); 4423 ASSERT_NE(device, nullptr); 4424 device3_x = device; 4425 }); 4426 ASSERT_TRUE(ret.isOk()); 4427 4428 sp<DeviceCb> cb = new DeviceCb(this); 4429 sp<ICameraDeviceSession> session; 4430 ret = device3_x->open( 4431 cb, 4432 [&session](auto status, const auto& newSession) { 4433 ALOGI("device::open returns status:%d", (int)status); 4434 ASSERT_EQ(Status::OK, status); 4435 ASSERT_NE(newSession, nullptr); 4436 session = newSession; 4437 }); 4438 ASSERT_TRUE(ret.isOk()); 4439 4440 sp<device::V3_3::ICameraDeviceSession> session3_3; 4441 castSession(session, deviceVersion, &session3_3, session3_4); 4442 ASSERT_NE(nullptr, session3_4); 4443 4444 camera_metadata_t *staticMeta; 4445 ret = device3_x->getCameraCharacteristics([&] (Status s, 4446 CameraMetadata metadata) { 4447 ASSERT_EQ(Status::OK, s); 4448 staticMeta = clone_camera_metadata( 4449 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 4450 ASSERT_NE(nullptr, staticMeta); 4451 }); 4452 ASSERT_TRUE(ret.isOk()); 4453 4454 camera_metadata_ro_entry entry; 4455 auto status = find_camera_metadata_ro_entry(staticMeta, 4456 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); 4457 if ((0 == status) && (entry.count > 0)) { 4458 *partialResultCount = entry.data.i32[0]; 4459 *supportsPartialResults = (*partialResultCount > 1); 4460 } 4461 4462 outputPreviewStreams.clear(); 4463 auto rc = getAvailableOutputStreams(staticMeta, 4464 outputPreviewStreams, previewThreshold); 4465 free_camera_metadata(staticMeta); 4466 ASSERT_EQ(Status::OK, rc); 4467 ASSERT_FALSE(outputPreviewStreams.empty()); 4468 4469 ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(physicalIds.size()); 4470 int32_t streamId = 0; 4471 for (auto const& physicalId : physicalIds) { 4472 V3_4::Stream stream3_4 = {{streamId, StreamType::OUTPUT, 4473 static_cast<uint32_t> (outputPreviewStreams[0].width), 4474 static_cast<uint32_t> (outputPreviewStreams[0].height), 4475 static_cast<PixelFormat> (outputPreviewStreams[0].format), 4476 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}, 4477 physicalId.c_str(), /*bufferSize*/ 0}; 4478 streams3_4[streamId++] = stream3_4; 4479 } 4480 4481 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 4482 config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}}; 4483 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 4484 ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate, 4485 [&config3_4](auto status, const auto& req) { 4486 ASSERT_EQ(Status::OK, status); 4487 config3_4.sessionParams = req; 4488 }); 4489 ASSERT_TRUE(ret.isOk()); 4490 4491 ret = (*session3_4)->configureStreams_3_4(config3_4, 4492 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) { 4493 ASSERT_EQ(Status::OK, s); 4494 ASSERT_EQ(physicalIds.size(), halConfig.streams.size()); 4495 *halStreamConfig = halConfig; 4496 }); 4497 *previewStream = streams3_4[0].v3_2; 4498 ASSERT_TRUE(ret.isOk()); 4499 } 4500 4501 // Open a device session and configure a preview stream. 4502 void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, 4503 sp<ICameraProvider> provider, 4504 const AvailableStream *previewThreshold, 4505 sp<ICameraDeviceSession> *session /*out*/, 4506 V3_2::Stream *previewStream /*out*/, 4507 HalStreamConfiguration *halStreamConfig /*out*/, 4508 bool *supportsPartialResults /*out*/, 4509 uint32_t *partialResultCount /*out*/) { 4510 ASSERT_NE(nullptr, session); 4511 ASSERT_NE(nullptr, previewStream); 4512 ASSERT_NE(nullptr, halStreamConfig); 4513 ASSERT_NE(nullptr, supportsPartialResults); 4514 ASSERT_NE(nullptr, partialResultCount); 4515 4516 std::vector<AvailableStream> outputPreviewStreams; 4517 ::android::sp<ICameraDevice> device3_x; 4518 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 4519 Return<void> ret; 4520 ret = provider->getCameraDeviceInterface_V3_x( 4521 name, 4522 [&](auto status, const auto& device) { 4523 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 4524 (int)status); 4525 ASSERT_EQ(Status::OK, status); 4526 ASSERT_NE(device, nullptr); 4527 device3_x = device; 4528 }); 4529 ASSERT_TRUE(ret.isOk()); 4530 4531 sp<DeviceCb> cb = new DeviceCb(this); 4532 ret = device3_x->open( 4533 cb, 4534 [&](auto status, const auto& newSession) { 4535 ALOGI("device::open returns status:%d", (int)status); 4536 ASSERT_EQ(Status::OK, status); 4537 ASSERT_NE(newSession, nullptr); 4538 *session = newSession; 4539 }); 4540 ASSERT_TRUE(ret.isOk()); 4541 4542 sp<device::V3_3::ICameraDeviceSession> session3_3; 4543 sp<device::V3_4::ICameraDeviceSession> session3_4; 4544 castSession(*session, deviceVersion, &session3_3, &session3_4); 4545 4546 camera_metadata_t *staticMeta; 4547 ret = device3_x->getCameraCharacteristics([&] (Status s, 4548 CameraMetadata metadata) { 4549 ASSERT_EQ(Status::OK, s); 4550 staticMeta = clone_camera_metadata( 4551 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 4552 ASSERT_NE(nullptr, staticMeta); 4553 }); 4554 ASSERT_TRUE(ret.isOk()); 4555 4556 camera_metadata_ro_entry entry; 4557 auto status = find_camera_metadata_ro_entry(staticMeta, 4558 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); 4559 if ((0 == status) && (entry.count > 0)) { 4560 *partialResultCount = entry.data.i32[0]; 4561 *supportsPartialResults = (*partialResultCount > 1); 4562 } 4563 4564 outputPreviewStreams.clear(); 4565 auto rc = getAvailableOutputStreams(staticMeta, 4566 outputPreviewStreams, previewThreshold); 4567 free_camera_metadata(staticMeta); 4568 ASSERT_EQ(Status::OK, rc); 4569 ASSERT_FALSE(outputPreviewStreams.empty()); 4570 4571 V3_2::Stream stream3_2 = {0, StreamType::OUTPUT, 4572 static_cast<uint32_t> (outputPreviewStreams[0].width), 4573 static_cast<uint32_t> (outputPreviewStreams[0].height), 4574 static_cast<PixelFormat> (outputPreviewStreams[0].format), 4575 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}; 4576 ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2}; 4577 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; 4578 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; 4579 createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, 4580 &config3_2, &config3_4); 4581 if (session3_4 != nullptr) { 4582 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 4583 ret = session3_4->constructDefaultRequestSettings(reqTemplate, 4584 [&config3_4](auto status, const auto& req) { 4585 ASSERT_EQ(Status::OK, status); 4586 config3_4.sessionParams = req; 4587 }); 4588 ASSERT_TRUE(ret.isOk()); 4589 ret = session3_4->configureStreams_3_4(config3_4, 4590 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) { 4591 ASSERT_EQ(Status::OK, s); 4592 ASSERT_EQ(1u, halConfig.streams.size()); 4593 halStreamConfig->streams.resize(halConfig.streams.size()); 4594 for (size_t i = 0; i < halConfig.streams.size(); i++) { 4595 halStreamConfig->streams[i] = halConfig.streams[i].v3_3.v3_2; 4596 } 4597 }); 4598 } else if (session3_3 != nullptr) { 4599 ret = session3_3->configureStreams_3_3(config3_2, 4600 [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) { 4601 ASSERT_EQ(Status::OK, s); 4602 ASSERT_EQ(1u, halConfig.streams.size()); 4603 halStreamConfig->streams.resize(halConfig.streams.size()); 4604 for (size_t i = 0; i < halConfig.streams.size(); i++) { 4605 halStreamConfig->streams[i] = halConfig.streams[i].v3_2; 4606 } 4607 }); 4608 } else { 4609 ret = (*session)->configureStreams(config3_2, 4610 [&] (Status s, HalStreamConfiguration halConfig) { 4611 ASSERT_EQ(Status::OK, s); 4612 ASSERT_EQ(1u, halConfig.streams.size()); 4613 *halStreamConfig = halConfig; 4614 }); 4615 } 4616 *previewStream = stream3_2; 4617 ASSERT_TRUE(ret.isOk()); 4618 } 4619 4620 //Cast camera device session to corresponding version 4621 void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion, 4622 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, 4623 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/) { 4624 ASSERT_NE(nullptr, session3_3); 4625 ASSERT_NE(nullptr, session3_4); 4626 4627 switch (deviceVersion) { 4628 case CAMERA_DEVICE_API_VERSION_3_4: { 4629 auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session); 4630 ASSERT_TRUE(castResult.isOk()); 4631 *session3_4 = castResult; 4632 break; 4633 } 4634 case CAMERA_DEVICE_API_VERSION_3_3: { 4635 auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session); 4636 ASSERT_TRUE(castResult.isOk()); 4637 *session3_3 = castResult; 4638 break; 4639 } 4640 default: 4641 //no-op 4642 return; 4643 } 4644 } 4645 4646 // Open a device session with empty callbacks and return static metadata. 4647 void CameraHidlTest::openEmptyDeviceSession(const std::string &name, 4648 sp<ICameraProvider> provider, 4649 sp<ICameraDeviceSession> *session /*out*/, 4650 camera_metadata_t **staticMeta /*out*/) { 4651 ASSERT_NE(nullptr, session); 4652 ASSERT_NE(nullptr, staticMeta); 4653 4654 ::android::sp<ICameraDevice> device3_x; 4655 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 4656 Return<void> ret; 4657 ret = provider->getCameraDeviceInterface_V3_x( 4658 name, 4659 [&](auto status, const auto& device) { 4660 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 4661 (int)status); 4662 ASSERT_EQ(Status::OK, status); 4663 ASSERT_NE(device, nullptr); 4664 device3_x = device; 4665 }); 4666 ASSERT_TRUE(ret.isOk()); 4667 4668 sp<EmptyDeviceCb> cb = new EmptyDeviceCb(); 4669 ret = device3_x->open(cb, [&](auto status, const auto& newSession) { 4670 ALOGI("device::open returns status:%d", (int)status); 4671 ASSERT_EQ(Status::OK, status); 4672 ASSERT_NE(newSession, nullptr); 4673 *session = newSession; 4674 }); 4675 ASSERT_TRUE(ret.isOk()); 4676 4677 ret = device3_x->getCameraCharacteristics([&] (Status s, 4678 CameraMetadata metadata) { 4679 ASSERT_EQ(Status::OK, s); 4680 *staticMeta = clone_camera_metadata( 4681 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 4682 ASSERT_NE(nullptr, *staticMeta); 4683 }); 4684 ASSERT_TRUE(ret.isOk()); 4685 } 4686 4687 // Open a particular camera device. 4688 void CameraHidlTest::openCameraDevice(const std::string &name, 4689 sp<ICameraProvider> provider, 4690 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) { 4691 ASSERT_TRUE(nullptr != device1); 4692 4693 Return<void> ret; 4694 ret = provider->getCameraDeviceInterface_V1_x( 4695 name, 4696 [&](auto status, const auto& device) { 4697 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 4698 (int)status); 4699 ASSERT_EQ(Status::OK, status); 4700 ASSERT_NE(device, nullptr); 4701 *device1 = device; 4702 }); 4703 ASSERT_TRUE(ret.isOk()); 4704 4705 sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this); 4706 Return<Status> returnStatus = (*device1)->open(deviceCb); 4707 ASSERT_TRUE(returnStatus.isOk()); 4708 ASSERT_EQ(Status::OK, returnStatus); 4709 } 4710 4711 // Initialize and configure a preview window. 4712 void CameraHidlTest::setupPreviewWindow( 4713 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 4714 sp<BufferItemConsumer> *bufferItemConsumer /*out*/, 4715 sp<BufferItemHander> *bufferHandler /*out*/) { 4716 ASSERT_NE(nullptr, device.get()); 4717 ASSERT_NE(nullptr, bufferItemConsumer); 4718 ASSERT_NE(nullptr, bufferHandler); 4719 4720 sp<IGraphicBufferProducer> producer; 4721 sp<IGraphicBufferConsumer> consumer; 4722 BufferQueue::createBufferQueue(&producer, &consumer); 4723 *bufferItemConsumer = new BufferItemConsumer(consumer, 4724 GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags 4725 ASSERT_NE(nullptr, (*bufferItemConsumer).get()); 4726 *bufferHandler = new BufferItemHander(*bufferItemConsumer); 4727 ASSERT_NE(nullptr, (*bufferHandler).get()); 4728 (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler); 4729 sp<Surface> surface = new Surface(producer); 4730 sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface); 4731 4732 auto rc = device->setPreviewWindow(previewCb); 4733 ASSERT_TRUE(rc.isOk()); 4734 ASSERT_EQ(Status::OK, rc); 4735 } 4736 4737 // Stop camera preview and close camera. 4738 void CameraHidlTest::stopPreviewAndClose( 4739 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 4740 Return<void> ret = device->stopPreview(); 4741 ASSERT_TRUE(ret.isOk()); 4742 4743 ret = device->close(); 4744 ASSERT_TRUE(ret.isOk()); 4745 } 4746 4747 // Enable a specific camera message type. 4748 void CameraHidlTest::enableMsgType(unsigned int msgType, 4749 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 4750 Return<void> ret = device->enableMsgType(msgType); 4751 ASSERT_TRUE(ret.isOk()); 4752 4753 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType); 4754 ASSERT_TRUE(returnBoolStatus.isOk()); 4755 ASSERT_TRUE(returnBoolStatus); 4756 } 4757 4758 // Disable a specific camera message type. 4759 void CameraHidlTest::disableMsgType(unsigned int msgType, 4760 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 4761 Return<void> ret = device->disableMsgType(msgType); 4762 ASSERT_TRUE(ret.isOk()); 4763 4764 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType); 4765 ASSERT_TRUE(returnBoolStatus.isOk()); 4766 ASSERT_FALSE(returnBoolStatus); 4767 } 4768 4769 // Wait until a specific frame notification arrives. 4770 void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame, 4771 std::unique_lock<std::mutex> &l) { 4772 while (msgFrame != mDataMessageTypeReceived) { 4773 auto timeout = std::chrono::system_clock::now() + 4774 std::chrono::seconds(kStreamBufferTimeoutSec); 4775 ASSERT_NE(std::cv_status::timeout, 4776 mResultCondition.wait_until(l, timeout)); 4777 } 4778 } 4779 4780 // Start preview on a particular camera device 4781 void CameraHidlTest::startPreview( 4782 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 4783 Return<Status> returnStatus = device->startPreview(); 4784 ASSERT_TRUE(returnStatus.isOk()); 4785 ASSERT_EQ(Status::OK, returnStatus); 4786 } 4787 4788 // Retrieve camera parameters. 4789 void CameraHidlTest::getParameters( 4790 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 4791 CameraParameters *cameraParams /*out*/) { 4792 ASSERT_NE(nullptr, cameraParams); 4793 4794 Return<void> ret; 4795 ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) { 4796 ASSERT_FALSE(params.empty()); 4797 ::android::String8 paramString(params.c_str()); 4798 (*cameraParams).unflatten(paramString); 4799 }); 4800 ASSERT_TRUE(ret.isOk()); 4801 } 4802 4803 // Set camera parameters. 4804 void CameraHidlTest::setParameters( 4805 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 4806 const CameraParameters &cameraParams) { 4807 Return<Status> returnStatus = device->setParameters( 4808 cameraParams.flatten().string()); 4809 ASSERT_TRUE(returnStatus.isOk()); 4810 ASSERT_EQ(Status::OK, returnStatus); 4811 } 4812 4813 void CameraHidlTest::allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage, 4814 PixelFormat format, hidl_handle *buffer_handle /*out*/) { 4815 ASSERT_NE(buffer_handle, nullptr); 4816 4817 sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator = 4818 android::hardware::graphics::allocator::V2_0::IAllocator::getService(); 4819 ASSERT_NE(nullptr, allocator.get()); 4820 4821 sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper = 4822 android::hardware::graphics::mapper::V2_0::IMapper::getService(); 4823 ASSERT_NE(mapper.get(), nullptr); 4824 4825 android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {}; 4826 descriptorInfo.width = width; 4827 descriptorInfo.height = height; 4828 descriptorInfo.layerCount = 1; 4829 descriptorInfo.format = format; 4830 descriptorInfo.usage = usage; 4831 4832 ::android::hardware::hidl_vec<uint32_t> descriptor; 4833 auto ret = mapper->createDescriptor( 4834 descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err, 4835 ::android::hardware::hidl_vec<uint32_t> desc) { 4836 ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE); 4837 descriptor = desc; 4838 }); 4839 ASSERT_TRUE(ret.isOk()); 4840 4841 ret = allocator->allocate(descriptor, 1u, 4842 [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/, 4843 const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) { 4844 ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err); 4845 ASSERT_EQ(buffers.size(), 1u); 4846 *buffer_handle = buffers[0]; 4847 }); 4848 ASSERT_TRUE(ret.isOk()); 4849 } 4850 4851 int main(int argc, char **argv) { 4852 ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance()); 4853 ::testing::InitGoogleTest(&argc, argv); 4854 CameraHidlEnvironment::Instance()->init(&argc, argv); 4855 int status = RUN_ALL_TESTS(); 4856 ALOGI("Test result = %d", status); 4857 return status; 4858 } 4859