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