VtsHalCameraProviderV2_4TargetTest.cpp revision e18057b42f1698f33f34d14e86a53934bd337bb8
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 ASSERT_TRUE(ret.isOk()); 1920 } 1921 break; 1922 case CAMERA_DEVICE_API_VERSION_1_0: { 1923 //Not applicable 1924 } 1925 break; 1926 default: { 1927 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 1928 ADD_FAILURE(); 1929 } 1930 break; 1931 } 1932 } 1933} 1934 1935//In case it is supported verify that torch can be enabled. 1936//Check for corresponding toch callbacks as well. 1937TEST_F(CameraHidlTest, setTorchMode) { 1938 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 1939 bool torchControlSupported = false; 1940 Return<void> ret; 1941 1942 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) { 1943 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support); 1944 ASSERT_EQ(Status::OK, status); 1945 torchControlSupported = support; 1946 }); 1947 1948 sp<TorchProviderCb> cb = new TorchProviderCb(this); 1949 Return<Status> returnStatus = mProvider->setCallback(cb); 1950 ASSERT_TRUE(returnStatus.isOk()); 1951 ASSERT_EQ(Status::OK, returnStatus); 1952 1953 for (const auto& name : cameraDeviceNames) { 1954 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 1955 switch (deviceVersion) { 1956 case CAMERA_DEVICE_API_VERSION_3_4: 1957 case CAMERA_DEVICE_API_VERSION_3_3: 1958 case CAMERA_DEVICE_API_VERSION_3_2: { 1959 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 1960 ALOGI("setTorchMode: Testing camera device %s", name.c_str()); 1961 ret = mProvider->getCameraDeviceInterface_V3_x( 1962 name, [&](auto status, const auto& device) { 1963 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 1964 ASSERT_EQ(Status::OK, status); 1965 ASSERT_NE(device, nullptr); 1966 device3_x = device; 1967 }); 1968 ASSERT_TRUE(ret.isOk()); 1969 1970 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 1971 returnStatus = device3_x->setTorchMode(TorchMode::ON); 1972 ASSERT_TRUE(returnStatus.isOk()); 1973 if (!torchControlSupported) { 1974 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus); 1975 } else { 1976 ASSERT_TRUE(returnStatus == Status::OK || 1977 returnStatus == Status::OPERATION_NOT_SUPPORTED); 1978 if (returnStatus == Status::OK) { 1979 { 1980 std::unique_lock<std::mutex> l(mTorchLock); 1981 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 1982 auto timeout = std::chrono::system_clock::now() + 1983 std::chrono::seconds(kTorchTimeoutSec); 1984 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout)); 1985 } 1986 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus); 1987 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 1988 } 1989 1990 returnStatus = device3_x->setTorchMode(TorchMode::OFF); 1991 ASSERT_TRUE(returnStatus.isOk()); 1992 ASSERT_EQ(Status::OK, returnStatus); 1993 1994 { 1995 std::unique_lock<std::mutex> l(mTorchLock); 1996 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 1997 auto timeout = std::chrono::system_clock::now() + 1998 std::chrono::seconds(kTorchTimeoutSec); 1999 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout)); 2000 } 2001 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus); 2002 } 2003 } 2004 } 2005 } 2006 break; 2007 case CAMERA_DEVICE_API_VERSION_1_0: { 2008 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2009 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2010 ret = mProvider->getCameraDeviceInterface_V1_x( 2011 name, [&](auto status, const auto& device) { 2012 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 2013 ASSERT_EQ(Status::OK, status); 2014 ASSERT_NE(device, nullptr); 2015 device1 = device; 2016 }); 2017 ASSERT_TRUE(ret.isOk()); 2018 2019 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2020 returnStatus = device1->setTorchMode(TorchMode::ON); 2021 ASSERT_TRUE(returnStatus.isOk()); 2022 if (!torchControlSupported) { 2023 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus); 2024 } else { 2025 ASSERT_TRUE(returnStatus == Status::OK || 2026 returnStatus == Status::OPERATION_NOT_SUPPORTED); 2027 if (returnStatus == Status::OK) { 2028 { 2029 std::unique_lock<std::mutex> l(mTorchLock); 2030 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2031 auto timeout = std::chrono::system_clock::now() + 2032 std::chrono::seconds(kTorchTimeoutSec); 2033 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, 2034 timeout)); 2035 } 2036 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus); 2037 mTorchStatus = TorchModeStatus::NOT_AVAILABLE; 2038 } 2039 2040 returnStatus = device1->setTorchMode(TorchMode::OFF); 2041 ASSERT_TRUE(returnStatus.isOk()); 2042 ASSERT_EQ(Status::OK, returnStatus); 2043 2044 { 2045 std::unique_lock<std::mutex> l(mTorchLock); 2046 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) { 2047 auto timeout = std::chrono::system_clock::now() + 2048 std::chrono::seconds(kTorchTimeoutSec); 2049 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, 2050 timeout)); 2051 } 2052 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus); 2053 } 2054 } 2055 } 2056 ret = device1->close(); 2057 ASSERT_TRUE(ret.isOk()); 2058 } 2059 break; 2060 default: { 2061 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2062 ADD_FAILURE(); 2063 } 2064 break; 2065 } 2066 } 2067 2068 returnStatus = mProvider->setCallback(nullptr); 2069 ASSERT_TRUE(returnStatus.isOk()); 2070 ASSERT_EQ(Status::OK, returnStatus); 2071} 2072 2073// Check dump functionality. 2074TEST_F(CameraHidlTest, dumpState) { 2075 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2076 Return<void> ret; 2077 2078 for (const auto& name : cameraDeviceNames) { 2079 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2080 switch (deviceVersion) { 2081 case CAMERA_DEVICE_API_VERSION_3_4: 2082 case CAMERA_DEVICE_API_VERSION_3_3: 2083 case CAMERA_DEVICE_API_VERSION_3_2: { 2084 ::android::sp<ICameraDevice> device3_x; 2085 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2086 ret = mProvider->getCameraDeviceInterface_V3_x( 2087 name, [&](auto status, const auto& device) { 2088 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2089 ASSERT_EQ(Status::OK, status); 2090 ASSERT_NE(device, nullptr); 2091 device3_x = device; 2092 }); 2093 ASSERT_TRUE(ret.isOk()); 2094 2095 native_handle_t* raw_handle = native_handle_create(1, 0); 2096 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2097 ASSERT_GE(raw_handle->data[0], 0); 2098 hidl_handle handle = raw_handle; 2099 ret = device3_x->dumpState(handle); 2100 ASSERT_TRUE(ret.isOk()); 2101 close(raw_handle->data[0]); 2102 native_handle_delete(raw_handle); 2103 } 2104 break; 2105 case CAMERA_DEVICE_API_VERSION_1_0: { 2106 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2107 ALOGI("dumpState: Testing camera device %s", name.c_str()); 2108 ret = mProvider->getCameraDeviceInterface_V1_x( 2109 name, [&](auto status, const auto& device) { 2110 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status); 2111 ASSERT_EQ(Status::OK, status); 2112 ASSERT_NE(device, nullptr); 2113 device1 = device; 2114 }); 2115 ASSERT_TRUE(ret.isOk()); 2116 2117 native_handle_t* raw_handle = native_handle_create(1, 0); 2118 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2119 ASSERT_GE(raw_handle->data[0], 0); 2120 hidl_handle handle = raw_handle; 2121 Return<Status> returnStatus = device1->dumpState(handle); 2122 ASSERT_TRUE(returnStatus.isOk()); 2123 ASSERT_EQ(Status::OK, returnStatus); 2124 close(raw_handle->data[0]); 2125 native_handle_delete(raw_handle); 2126 } 2127 break; 2128 default: { 2129 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2130 ADD_FAILURE(); 2131 } 2132 break; 2133 } 2134 } 2135} 2136 2137// Open, dumpStates, then close 2138TEST_F(CameraHidlTest, openClose) { 2139 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2140 Return<void> ret; 2141 2142 for (const auto& name : cameraDeviceNames) { 2143 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2144 switch (deviceVersion) { 2145 case CAMERA_DEVICE_API_VERSION_3_4: 2146 case CAMERA_DEVICE_API_VERSION_3_3: 2147 case CAMERA_DEVICE_API_VERSION_3_2: { 2148 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 2149 ALOGI("openClose: Testing camera device %s", name.c_str()); 2150 ret = mProvider->getCameraDeviceInterface_V3_x( 2151 name, [&](auto status, const auto& device) { 2152 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2153 ASSERT_EQ(Status::OK, status); 2154 ASSERT_NE(device, nullptr); 2155 device3_x = device; 2156 }); 2157 ASSERT_TRUE(ret.isOk()); 2158 2159 sp<EmptyDeviceCb> cb = new EmptyDeviceCb; 2160 sp<ICameraDeviceSession> session; 2161 ret = device3_x->open(cb, [&](auto status, const auto& newSession) { 2162 ALOGI("device::open returns status:%d", (int)status); 2163 ASSERT_EQ(Status::OK, status); 2164 ASSERT_NE(newSession, nullptr); 2165 session = newSession; 2166 }); 2167 ASSERT_TRUE(ret.isOk()); 2168 // Ensure that a device labeling itself as 3.3/3.4 can have its session interface 2169 // cast the 3.3/3.4 interface, and that lower versions can't be cast to it. 2170 sp<device::V3_3::ICameraDeviceSession> sessionV3_3; 2171 sp<device::V3_4::ICameraDeviceSession> sessionV3_4; 2172 castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4); 2173 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { 2174 ASSERT_TRUE(sessionV3_4.get() != nullptr); 2175 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) { 2176 ASSERT_TRUE(sessionV3_3.get() != nullptr); 2177 } else { 2178 ASSERT_TRUE(sessionV3_3.get() == nullptr); 2179 } 2180 native_handle_t* raw_handle = native_handle_create(1, 0); 2181 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2182 ASSERT_GE(raw_handle->data[0], 0); 2183 hidl_handle handle = raw_handle; 2184 ret = device3_x->dumpState(handle); 2185 ASSERT_TRUE(ret.isOk()); 2186 close(raw_handle->data[0]); 2187 native_handle_delete(raw_handle); 2188 2189 ret = session->close(); 2190 ASSERT_TRUE(ret.isOk()); 2191 // TODO: test all session API calls return INTERNAL_ERROR after close 2192 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope 2193 } 2194 break; 2195 case CAMERA_DEVICE_API_VERSION_1_0: { 2196 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1; 2197 openCameraDevice(name, mProvider, &device1 /*out*/); 2198 ASSERT_NE(nullptr, device1.get()); 2199 2200 native_handle_t* raw_handle = native_handle_create(1, 0); 2201 raw_handle->data[0] = open(kDumpOutput, O_RDWR); 2202 ASSERT_GE(raw_handle->data[0], 0); 2203 hidl_handle handle = raw_handle; 2204 Return<Status> returnStatus = device1->dumpState(handle); 2205 ASSERT_TRUE(returnStatus.isOk()); 2206 ASSERT_EQ(Status::OK, returnStatus); 2207 close(raw_handle->data[0]); 2208 native_handle_delete(raw_handle); 2209 2210 ret = device1->close(); 2211 ASSERT_TRUE(ret.isOk()); 2212 } 2213 break; 2214 default: { 2215 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2216 ADD_FAILURE(); 2217 } 2218 break; 2219 } 2220 } 2221} 2222 2223// Check whether all common default request settings can be sucessfully 2224// constructed. 2225TEST_F(CameraHidlTest, constructDefaultRequestSettings) { 2226 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2227 2228 for (const auto& name : cameraDeviceNames) { 2229 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2230 switch (deviceVersion) { 2231 case CAMERA_DEVICE_API_VERSION_3_4: 2232 case CAMERA_DEVICE_API_VERSION_3_3: 2233 case CAMERA_DEVICE_API_VERSION_3_2: { 2234 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; 2235 Return<void> ret; 2236 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str()); 2237 ret = mProvider->getCameraDeviceInterface_V3_x( 2238 name, [&](auto status, const auto& device) { 2239 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status); 2240 ASSERT_EQ(Status::OK, status); 2241 ASSERT_NE(device, nullptr); 2242 device3_x = device; 2243 }); 2244 ASSERT_TRUE(ret.isOk()); 2245 2246 sp<EmptyDeviceCb> cb = new EmptyDeviceCb; 2247 sp<ICameraDeviceSession> session; 2248 ret = device3_x->open(cb, [&](auto status, const auto& newSession) { 2249 ALOGI("device::open returns status:%d", (int)status); 2250 ASSERT_EQ(Status::OK, status); 2251 ASSERT_NE(newSession, nullptr); 2252 session = newSession; 2253 }); 2254 ASSERT_TRUE(ret.isOk()); 2255 2256 for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW; 2257 t <= (uint32_t)RequestTemplate::MANUAL; t++) { 2258 RequestTemplate reqTemplate = (RequestTemplate)t; 2259 ret = 2260 session->constructDefaultRequestSettings( 2261 reqTemplate, [&](auto status, const auto& req) { 2262 ALOGI("constructDefaultRequestSettings returns status:%d", 2263 (int)status); 2264 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG || 2265 reqTemplate == RequestTemplate::MANUAL) { 2266 // optional templates 2267 ASSERT_TRUE((status == Status::OK) || 2268 (status == Status::ILLEGAL_ARGUMENT)); 2269 } else { 2270 ASSERT_EQ(Status::OK, status); 2271 } 2272 2273 if (status == Status::OK) { 2274 const camera_metadata_t* metadata = 2275 (camera_metadata_t*) req.data(); 2276 size_t expectedSize = req.size(); 2277 int result = validate_camera_metadata_structure( 2278 metadata, &expectedSize); 2279 ASSERT_TRUE((result == 0) || 2280 (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 2281 size_t entryCount = 2282 get_camera_metadata_entry_count(metadata); 2283 // TODO: we can do better than 0 here. Need to check how many required 2284 // request keys we've defined for each template 2285 ASSERT_GT(entryCount, 0u); 2286 ALOGI("template %u metadata entry count is %zu", 2287 t, entryCount); 2288 } else { 2289 ASSERT_EQ(0u, req.size()); 2290 } 2291 }); 2292 ASSERT_TRUE(ret.isOk()); 2293 } 2294 ret = session->close(); 2295 ASSERT_TRUE(ret.isOk()); 2296 } 2297 break; 2298 case CAMERA_DEVICE_API_VERSION_1_0: { 2299 //Not applicable 2300 } 2301 break; 2302 default: { 2303 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2304 ADD_FAILURE(); 2305 } 2306 break; 2307 } 2308 } 2309} 2310 2311 2312// Verify that all supported stream formats and sizes can be configured 2313// successfully. 2314TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) { 2315 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2316 std::vector<AvailableStream> outputStreams; 2317 2318 for (const auto& name : cameraDeviceNames) { 2319 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2320 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2321 continue; 2322 } else if (deviceVersion <= 0) { 2323 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2324 ADD_FAILURE(); 2325 return; 2326 } 2327 2328 camera_metadata_t* staticMeta; 2329 Return<void> ret; 2330 sp<ICameraDeviceSession> session; 2331 sp<device::V3_3::ICameraDeviceSession> session3_3; 2332 sp<device::V3_4::ICameraDeviceSession> session3_4; 2333 openEmptyDeviceSession(name, mProvider, 2334 &session /*out*/, &staticMeta /*out*/); 2335 castSession(session, deviceVersion, &session3_3, &session3_4); 2336 2337 outputStreams.clear(); 2338 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); 2339 ASSERT_NE(0u, outputStreams.size()); 2340 2341 int32_t streamId = 0; 2342 for (auto& it : outputStreams) { 2343 Stream stream = {streamId, 2344 StreamType::OUTPUT, 2345 static_cast<uint32_t>(it.width), 2346 static_cast<uint32_t>(it.height), 2347 static_cast<PixelFormat>(it.format), 2348 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2349 0, 2350 StreamRotation::ROTATION_0}; 2351 ::android::hardware::hidl_vec<Stream> streams = {stream}; 2352 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2353 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2354 if (session3_4 != nullptr) { 2355 ret = session3_4->configureStreams_3_4(config, 2356 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2357 ASSERT_EQ(Status::OK, s); 2358 ASSERT_EQ(1u, halConfig.streams.size()); 2359 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); 2360 }); 2361 } else if (session3_3 != nullptr) { 2362 ret = session3_3->configureStreams_3_3(config.v3_2, 2363 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2364 ASSERT_EQ(Status::OK, s); 2365 ASSERT_EQ(1u, halConfig.streams.size()); 2366 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); 2367 }); 2368 } else { 2369 ret = session->configureStreams(config.v3_2, 2370 [streamId](Status s, HalStreamConfiguration halConfig) { 2371 ASSERT_EQ(Status::OK, s); 2372 ASSERT_EQ(1u, halConfig.streams.size()); 2373 ASSERT_EQ(halConfig.streams[0].id, streamId); 2374 }); 2375 } 2376 ASSERT_TRUE(ret.isOk()); 2377 streamId++; 2378 } 2379 2380 free_camera_metadata(staticMeta); 2381 ret = session->close(); 2382 ASSERT_TRUE(ret.isOk()); 2383 } 2384} 2385 2386// Check for correct handling of invalid/incorrect configuration parameters. 2387TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) { 2388 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2389 std::vector<AvailableStream> outputStreams; 2390 2391 for (const auto& name : cameraDeviceNames) { 2392 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2393 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2394 continue; 2395 } else if (deviceVersion <= 0) { 2396 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2397 ADD_FAILURE(); 2398 return; 2399 } 2400 2401 camera_metadata_t* staticMeta; 2402 Return<void> ret; 2403 sp<ICameraDeviceSession> session; 2404 sp<device::V3_3::ICameraDeviceSession> session3_3; 2405 sp<device::V3_4::ICameraDeviceSession> session3_4; 2406 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2407 castSession(session, deviceVersion, &session3_3, &session3_4); 2408 2409 outputStreams.clear(); 2410 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); 2411 ASSERT_NE(0u, outputStreams.size()); 2412 2413 int32_t streamId = 0; 2414 Stream stream = {streamId++, 2415 StreamType::OUTPUT, 2416 static_cast<uint32_t>(0), 2417 static_cast<uint32_t>(0), 2418 static_cast<PixelFormat>(outputStreams[0].format), 2419 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2420 0, 2421 StreamRotation::ROTATION_0}; 2422 ::android::hardware::hidl_vec<Stream> streams = {stream}; 2423 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2424 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2425 if(session3_4 != nullptr) { 2426 ret = session3_4->configureStreams_3_4(config, 2427 [](Status s, device::V3_3::HalStreamConfiguration) { 2428 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2429 (Status::INTERNAL_ERROR == s)); 2430 }); 2431 } else if(session3_3 != nullptr) { 2432 ret = session3_3->configureStreams_3_3(config.v3_2, 2433 [](Status s, device::V3_3::HalStreamConfiguration) { 2434 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2435 (Status::INTERNAL_ERROR == s)); 2436 }); 2437 } else { 2438 ret = session->configureStreams(config.v3_2, 2439 [](Status s, HalStreamConfiguration) { 2440 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2441 (Status::INTERNAL_ERROR == s)); 2442 }); 2443 } 2444 ASSERT_TRUE(ret.isOk()); 2445 2446 stream = {streamId++, 2447 StreamType::OUTPUT, 2448 static_cast<uint32_t>(UINT32_MAX), 2449 static_cast<uint32_t>(UINT32_MAX), 2450 static_cast<PixelFormat>(outputStreams[0].format), 2451 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2452 0, 2453 StreamRotation::ROTATION_0}; 2454 streams[0] = stream; 2455 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2456 if(session3_4 != nullptr) { 2457 ret = session3_4->configureStreams_3_4(config, [](Status s, 2458 device::V3_3::HalStreamConfiguration) { 2459 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2460 }); 2461 } else if(session3_3 != nullptr) { 2462 ret = session3_3->configureStreams_3_3(config.v3_2, [](Status s, 2463 device::V3_3::HalStreamConfiguration) { 2464 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2465 }); 2466 } else { 2467 ret = session->configureStreams(config.v3_2, [](Status s, 2468 HalStreamConfiguration) { 2469 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2470 }); 2471 } 2472 ASSERT_TRUE(ret.isOk()); 2473 2474 for (auto& it : outputStreams) { 2475 stream = {streamId++, 2476 StreamType::OUTPUT, 2477 static_cast<uint32_t>(it.width), 2478 static_cast<uint32_t>(it.height), 2479 static_cast<PixelFormat>(UINT32_MAX), 2480 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2481 0, 2482 StreamRotation::ROTATION_0}; 2483 streams[0] = stream; 2484 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2485 if(session3_4 != nullptr) { 2486 ret = session3_4->configureStreams_3_4(config, 2487 [](Status s, device::V3_3::HalStreamConfiguration) { 2488 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2489 }); 2490 } else if(session3_3 != nullptr) { 2491 ret = session3_3->configureStreams_3_3(config.v3_2, 2492 [](Status s, device::V3_3::HalStreamConfiguration) { 2493 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2494 }); 2495 } else { 2496 ret = session->configureStreams(config.v3_2, 2497 [](Status s, HalStreamConfiguration) { 2498 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2499 }); 2500 } 2501 ASSERT_TRUE(ret.isOk()); 2502 2503 stream = {streamId++, 2504 StreamType::OUTPUT, 2505 static_cast<uint32_t>(it.width), 2506 static_cast<uint32_t>(it.height), 2507 static_cast<PixelFormat>(it.format), 2508 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2509 0, 2510 static_cast<StreamRotation>(UINT32_MAX)}; 2511 streams[0] = stream; 2512 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2513 if(session3_4 != nullptr) { 2514 ret = session3_4->configureStreams_3_4(config, 2515 [](Status s, device::V3_3::HalStreamConfiguration) { 2516 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2517 }); 2518 } else if(session3_3 != nullptr) { 2519 ret = session3_3->configureStreams_3_3(config.v3_2, 2520 [](Status s, device::V3_3::HalStreamConfiguration) { 2521 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2522 }); 2523 } else { 2524 ret = session->configureStreams(config.v3_2, 2525 [](Status s, HalStreamConfiguration) { 2526 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2527 }); 2528 } 2529 ASSERT_TRUE(ret.isOk()); 2530 } 2531 2532 free_camera_metadata(staticMeta); 2533 ret = session->close(); 2534 ASSERT_TRUE(ret.isOk()); 2535 } 2536} 2537 2538// Check whether all supported ZSL output stream combinations can be 2539// configured successfully. 2540TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) { 2541 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2542 std::vector<AvailableStream> inputStreams; 2543 std::vector<AvailableZSLInputOutput> inputOutputMap; 2544 2545 for (const auto& name : cameraDeviceNames) { 2546 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2547 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2548 continue; 2549 } else if (deviceVersion <= 0) { 2550 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2551 ADD_FAILURE(); 2552 return; 2553 } 2554 2555 camera_metadata_t* staticMeta; 2556 Return<void> ret; 2557 sp<ICameraDeviceSession> session; 2558 sp<device::V3_3::ICameraDeviceSession> session3_3; 2559 sp<device::V3_4::ICameraDeviceSession> session3_4; 2560 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2561 castSession(session, deviceVersion, &session3_3, &session3_4); 2562 2563 Status rc = isZSLModeAvailable(staticMeta); 2564 if (Status::METHOD_NOT_SUPPORTED == rc) { 2565 ret = session->close(); 2566 ASSERT_TRUE(ret.isOk()); 2567 continue; 2568 } 2569 ASSERT_EQ(Status::OK, rc); 2570 2571 inputStreams.clear(); 2572 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams)); 2573 ASSERT_NE(0u, inputStreams.size()); 2574 2575 inputOutputMap.clear(); 2576 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap)); 2577 ASSERT_NE(0u, inputOutputMap.size()); 2578 2579 int32_t streamId = 0; 2580 for (auto& inputIter : inputOutputMap) { 2581 AvailableStream input; 2582 ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat, 2583 input)); 2584 ASSERT_NE(0u, inputStreams.size()); 2585 2586 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX, 2587 inputIter.outputFormat}; 2588 std::vector<AvailableStream> outputStreams; 2589 ASSERT_EQ(Status::OK, 2590 getAvailableOutputStreams(staticMeta, outputStreams, 2591 &outputThreshold)); 2592 for (auto& outputIter : outputStreams) { 2593 Stream zslStream = {streamId++, 2594 StreamType::OUTPUT, 2595 static_cast<uint32_t>(input.width), 2596 static_cast<uint32_t>(input.height), 2597 static_cast<PixelFormat>(input.format), 2598 GRALLOC_USAGE_HW_CAMERA_ZSL, 2599 0, 2600 StreamRotation::ROTATION_0}; 2601 Stream inputStream = {streamId++, 2602 StreamType::INPUT, 2603 static_cast<uint32_t>(input.width), 2604 static_cast<uint32_t>(input.height), 2605 static_cast<PixelFormat>(input.format), 2606 0, 2607 0, 2608 StreamRotation::ROTATION_0}; 2609 Stream outputStream = {streamId++, 2610 StreamType::OUTPUT, 2611 static_cast<uint32_t>(outputIter.width), 2612 static_cast<uint32_t>(outputIter.height), 2613 static_cast<PixelFormat>(outputIter.format), 2614 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2615 0, 2616 StreamRotation::ROTATION_0}; 2617 2618 ::android::hardware::hidl_vec<Stream> streams = {inputStream, zslStream, 2619 outputStream}; 2620 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2621 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2622 if (session3_4 != nullptr) { 2623 ret = session3_4->configureStreams_3_4(config, 2624 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2625 ASSERT_EQ(Status::OK, s); 2626 ASSERT_EQ(3u, halConfig.streams.size()); 2627 }); 2628 } else if (session3_3 != nullptr) { 2629 ret = session3_3->configureStreams_3_3(config.v3_2, 2630 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2631 ASSERT_EQ(Status::OK, s); 2632 ASSERT_EQ(3u, halConfig.streams.size()); 2633 }); 2634 } else { 2635 ret = session->configureStreams(config.v3_2, 2636 [](Status s, HalStreamConfiguration halConfig) { 2637 ASSERT_EQ(Status::OK, s); 2638 ASSERT_EQ(3u, halConfig.streams.size()); 2639 }); 2640 } 2641 ASSERT_TRUE(ret.isOk()); 2642 } 2643 } 2644 2645 free_camera_metadata(staticMeta); 2646 ret = session->close(); 2647 ASSERT_TRUE(ret.isOk()); 2648 } 2649} 2650 2651// Check wehether session parameters are supported. If Hal support for them 2652// exist, then try to configure a preview stream using them. 2653TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) { 2654 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2655 std::vector<AvailableStream> outputPreviewStreams; 2656 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 2657 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2658 2659 for (const auto& name : cameraDeviceNames) { 2660 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2661 if (deviceVersion <= 0) { 2662 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2663 ADD_FAILURE(); 2664 return; 2665 } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) { 2666 continue; 2667 } 2668 2669 camera_metadata_t* staticMetaBuffer; 2670 Return<void> ret; 2671 sp<ICameraDeviceSession> session; 2672 sp<device::V3_3::ICameraDeviceSession> session3_3; 2673 sp<device::V3_4::ICameraDeviceSession> session3_4; 2674 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); 2675 castSession(session, deviceVersion, &session3_3, &session3_4); 2676 ASSERT_NE(session3_4, nullptr); 2677 2678 const android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta( 2679 staticMetaBuffer); 2680 camera_metadata_ro_entry availableSessionKeys = staticMeta.find( 2681 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS); 2682 if (availableSessionKeys.count == 0) { 2683 ret = session->close(); 2684 ASSERT_TRUE(ret.isOk()); 2685 continue; 2686 } 2687 2688 android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings; 2689 ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW, 2690 [&previewRequestSettings] (auto status, const auto& req) mutable { 2691 ASSERT_EQ(Status::OK, status); 2692 2693 const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> ( 2694 req.data()); 2695 size_t expectedSize = req.size(); 2696 int result = validate_camera_metadata_structure(metadata, &expectedSize); 2697 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED)); 2698 2699 size_t entryCount = get_camera_metadata_entry_count(metadata); 2700 ASSERT_GT(entryCount, 0u); 2701 previewRequestSettings = metadata; 2702 }); 2703 ASSERT_TRUE(ret.isOk()); 2704 const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings = 2705 previewRequestSettings; 2706 android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams; 2707 for (size_t i = 0; i < availableSessionKeys.count; i++) { 2708 camera_metadata_ro_entry entry = constSettings.find(availableSessionKeys.data.i32[i]); 2709 if (entry.count > 0) { 2710 sessionParams.update(entry); 2711 } 2712 } 2713 if (sessionParams.isEmpty()) { 2714 ret = session->close(); 2715 ASSERT_TRUE(ret.isOk()); 2716 continue; 2717 } 2718 2719 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams, 2720 &previewThreshold)); 2721 ASSERT_NE(0u, outputPreviewStreams.size()); 2722 2723 Stream previewStream = {0, 2724 StreamType::OUTPUT, 2725 static_cast<uint32_t>(outputPreviewStreams[0].width), 2726 static_cast<uint32_t>(outputPreviewStreams[0].height), 2727 static_cast<PixelFormat>(outputPreviewStreams[0].format), 2728 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2729 0, 2730 StreamRotation::ROTATION_0}; 2731 ::android::hardware::hidl_vec<Stream> streams = {previewStream}; 2732 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2733 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2734 const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock(); 2735 config.sessionParams.setToExternal( 2736 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (sessionParamsBuffer)), 2737 get_camera_metadata_size(sessionParamsBuffer)); 2738 ret = session3_4->configureStreams_3_4(config, 2739 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2740 ASSERT_EQ(Status::OK, s); 2741 ASSERT_EQ(1u, halConfig.streams.size()); 2742 }); 2743 ASSERT_TRUE(ret.isOk()); 2744 2745 sessionParams.unlock(sessionParamsBuffer); 2746 ret = session->close(); 2747 ASSERT_TRUE(ret.isOk()); 2748 } 2749} 2750 2751// Verify that all supported preview + still capture stream combinations 2752// can be configured successfully. 2753TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) { 2754 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2755 std::vector<AvailableStream> outputBlobStreams; 2756 std::vector<AvailableStream> outputPreviewStreams; 2757 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 2758 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 2759 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX, 2760 static_cast<int32_t>(PixelFormat::BLOB)}; 2761 2762 for (const auto& name : cameraDeviceNames) { 2763 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2764 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2765 continue; 2766 } else if (deviceVersion <= 0) { 2767 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2768 ADD_FAILURE(); 2769 return; 2770 } 2771 2772 camera_metadata_t* staticMeta; 2773 Return<void> ret; 2774 sp<ICameraDeviceSession> session; 2775 sp<device::V3_3::ICameraDeviceSession> session3_3; 2776 sp<device::V3_4::ICameraDeviceSession> session3_4; 2777 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2778 castSession(session, deviceVersion, &session3_3, &session3_4); 2779 2780 outputBlobStreams.clear(); 2781 ASSERT_EQ(Status::OK, 2782 getAvailableOutputStreams(staticMeta, outputBlobStreams, 2783 &blobThreshold)); 2784 ASSERT_NE(0u, outputBlobStreams.size()); 2785 2786 outputPreviewStreams.clear(); 2787 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams, 2788 &previewThreshold)); 2789 ASSERT_NE(0u, outputPreviewStreams.size()); 2790 2791 int32_t streamId = 0; 2792 for (auto& blobIter : outputBlobStreams) { 2793 for (auto& previewIter : outputPreviewStreams) { 2794 Stream previewStream = {streamId++, 2795 StreamType::OUTPUT, 2796 static_cast<uint32_t>(previewIter.width), 2797 static_cast<uint32_t>(previewIter.height), 2798 static_cast<PixelFormat>(previewIter.format), 2799 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 2800 0, 2801 StreamRotation::ROTATION_0}; 2802 Stream blobStream = {streamId++, 2803 StreamType::OUTPUT, 2804 static_cast<uint32_t>(blobIter.width), 2805 static_cast<uint32_t>(blobIter.height), 2806 static_cast<PixelFormat>(blobIter.format), 2807 GRALLOC1_CONSUMER_USAGE_CPU_READ, 2808 0, 2809 StreamRotation::ROTATION_0}; 2810 ::android::hardware::hidl_vec<Stream> streams = {previewStream, 2811 blobStream}; 2812 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2813 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 2814 if (session3_4 != nullptr) { 2815 ret = session3_4->configureStreams_3_4(config, 2816 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2817 ASSERT_EQ(Status::OK, s); 2818 ASSERT_EQ(2u, halConfig.streams.size()); 2819 }); 2820 } else if (session3_3 != nullptr) { 2821 ret = session3_3->configureStreams_3_3(config.v3_2, 2822 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2823 ASSERT_EQ(Status::OK, s); 2824 ASSERT_EQ(2u, halConfig.streams.size()); 2825 }); 2826 } else { 2827 ret = session->configureStreams(config.v3_2, 2828 [](Status s, HalStreamConfiguration halConfig) { 2829 ASSERT_EQ(Status::OK, s); 2830 ASSERT_EQ(2u, halConfig.streams.size()); 2831 }); 2832 } 2833 ASSERT_TRUE(ret.isOk()); 2834 } 2835 } 2836 2837 free_camera_metadata(staticMeta); 2838 ret = session->close(); 2839 ASSERT_TRUE(ret.isOk()); 2840 } 2841} 2842 2843// In case constrained mode is supported, test whether it can be 2844// configured. Additionally check for common invalid inputs when 2845// using this mode. 2846TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) { 2847 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 2848 2849 for (const auto& name : cameraDeviceNames) { 2850 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 2851 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 2852 continue; 2853 } else if (deviceVersion <= 0) { 2854 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 2855 ADD_FAILURE(); 2856 return; 2857 } 2858 2859 camera_metadata_t* staticMeta; 2860 Return<void> ret; 2861 sp<ICameraDeviceSession> session; 2862 sp<device::V3_3::ICameraDeviceSession> session3_3; 2863 sp<device::V3_4::ICameraDeviceSession> session3_4; 2864 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 2865 castSession(session, deviceVersion, &session3_3, &session3_4); 2866 2867 Status rc = isConstrainedModeAvailable(staticMeta); 2868 if (Status::METHOD_NOT_SUPPORTED == rc) { 2869 ret = session->close(); 2870 ASSERT_TRUE(ret.isOk()); 2871 continue; 2872 } 2873 ASSERT_EQ(Status::OK, rc); 2874 2875 AvailableStream hfrStream; 2876 rc = pickConstrainedModeSize(staticMeta, hfrStream); 2877 ASSERT_EQ(Status::OK, rc); 2878 2879 int32_t streamId = 0; 2880 Stream stream = {streamId, 2881 StreamType::OUTPUT, 2882 static_cast<uint32_t>(hfrStream.width), 2883 static_cast<uint32_t>(hfrStream.height), 2884 static_cast<PixelFormat>(hfrStream.format), 2885 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 2886 0, 2887 StreamRotation::ROTATION_0}; 2888 ::android::hardware::hidl_vec<Stream> streams = {stream}; 2889 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 2890 config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2891 if (session3_4 != nullptr) { 2892 ret = session3_4->configureStreams_3_4(config, 2893 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2894 ASSERT_EQ(Status::OK, s); 2895 ASSERT_EQ(1u, halConfig.streams.size()); 2896 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); 2897 }); 2898 } else if (session3_3 != nullptr) { 2899 ret = session3_3->configureStreams_3_3(config.v3_2, 2900 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) { 2901 ASSERT_EQ(Status::OK, s); 2902 ASSERT_EQ(1u, halConfig.streams.size()); 2903 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId); 2904 }); 2905 } else { 2906 ret = session->configureStreams(config.v3_2, 2907 [streamId](Status s, HalStreamConfiguration halConfig) { 2908 ASSERT_EQ(Status::OK, s); 2909 ASSERT_EQ(1u, halConfig.streams.size()); 2910 ASSERT_EQ(halConfig.streams[0].id, streamId); 2911 }); 2912 } 2913 ASSERT_TRUE(ret.isOk()); 2914 2915 stream = {streamId++, 2916 StreamType::OUTPUT, 2917 static_cast<uint32_t>(0), 2918 static_cast<uint32_t>(0), 2919 static_cast<PixelFormat>(hfrStream.format), 2920 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 2921 0, 2922 StreamRotation::ROTATION_0}; 2923 streams[0] = stream; 2924 config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2925 if (session3_4 != nullptr) { 2926 ret = session3_4->configureStreams_3_4(config, 2927 [](Status s, device::V3_3::HalStreamConfiguration) { 2928 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2929 (Status::INTERNAL_ERROR == s)); 2930 }); 2931 } else if (session3_3 != nullptr) { 2932 ret = session3_3->configureStreams_3_3(config.v3_2, 2933 [](Status s, device::V3_3::HalStreamConfiguration) { 2934 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2935 (Status::INTERNAL_ERROR == s)); 2936 }); 2937 } else { 2938 ret = session->configureStreams(config.v3_2, 2939 [](Status s, HalStreamConfiguration) { 2940 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || 2941 (Status::INTERNAL_ERROR == s)); 2942 }); 2943 } 2944 ASSERT_TRUE(ret.isOk()); 2945 2946 stream = {streamId++, 2947 StreamType::OUTPUT, 2948 static_cast<uint32_t>(UINT32_MAX), 2949 static_cast<uint32_t>(UINT32_MAX), 2950 static_cast<PixelFormat>(hfrStream.format), 2951 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 2952 0, 2953 StreamRotation::ROTATION_0}; 2954 streams[0] = stream; 2955 config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2956 if (session3_4 != nullptr) { 2957 ret = session3_4->configureStreams_3_4(config, 2958 [](Status s, device::V3_3::HalStreamConfiguration) { 2959 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2960 }); 2961 } else if (session3_3 != nullptr) { 2962 ret = session3_3->configureStreams_3_3(config.v3_2, 2963 [](Status s, device::V3_3::HalStreamConfiguration) { 2964 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2965 }); 2966 } else { 2967 ret = session->configureStreams(config.v3_2, 2968 [](Status s, HalStreamConfiguration) { 2969 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2970 }); 2971 } 2972 ASSERT_TRUE(ret.isOk()); 2973 2974 stream = {streamId++, 2975 StreamType::OUTPUT, 2976 static_cast<uint32_t>(hfrStream.width), 2977 static_cast<uint32_t>(hfrStream.height), 2978 static_cast<PixelFormat>(UINT32_MAX), 2979 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 2980 0, 2981 StreamRotation::ROTATION_0}; 2982 streams[0] = stream; 2983 config.v3_2 = {streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE}; 2984 if (session3_4 != nullptr) { 2985 ret = session3_4->configureStreams_3_4(config, 2986 [](Status s, device::V3_3::HalStreamConfiguration) { 2987 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2988 }); 2989 } else if (session3_3 != nullptr) { 2990 ret = session3_3->configureStreams_3_3(config.v3_2, 2991 [](Status s, device::V3_3::HalStreamConfiguration) { 2992 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2993 }); 2994 } else { 2995 ret = session->configureStreams(config.v3_2, 2996 [](Status s, HalStreamConfiguration) { 2997 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); 2998 }); 2999 } 3000 ASSERT_TRUE(ret.isOk()); 3001 3002 free_camera_metadata(staticMeta); 3003 ret = session->close(); 3004 ASSERT_TRUE(ret.isOk()); 3005 } 3006} 3007 3008// Verify that all supported video + snapshot stream combinations can 3009// be configured successfully. 3010TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) { 3011 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3012 std::vector<AvailableStream> outputBlobStreams; 3013 std::vector<AvailableStream> outputVideoStreams; 3014 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight, 3015 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3016 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight, 3017 static_cast<int32_t>(PixelFormat::BLOB)}; 3018 3019 for (const auto& name : cameraDeviceNames) { 3020 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3021 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3022 continue; 3023 } else if (deviceVersion <= 0) { 3024 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3025 ADD_FAILURE(); 3026 return; 3027 } 3028 3029 camera_metadata_t* staticMeta; 3030 Return<void> ret; 3031 sp<ICameraDeviceSession> session; 3032 sp<device::V3_3::ICameraDeviceSession> session3_3; 3033 sp<device::V3_4::ICameraDeviceSession> session3_4; 3034 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/); 3035 castSession(session, deviceVersion, &session3_3, &session3_4); 3036 3037 outputBlobStreams.clear(); 3038 ASSERT_EQ(Status::OK, 3039 getAvailableOutputStreams(staticMeta, outputBlobStreams, 3040 &blobThreshold)); 3041 ASSERT_NE(0u, outputBlobStreams.size()); 3042 3043 outputVideoStreams.clear(); 3044 ASSERT_EQ(Status::OK, 3045 getAvailableOutputStreams(staticMeta, outputVideoStreams, 3046 &videoThreshold)); 3047 ASSERT_NE(0u, outputVideoStreams.size()); 3048 3049 int32_t streamId = 0; 3050 for (auto& blobIter : outputBlobStreams) { 3051 for (auto& videoIter : outputVideoStreams) { 3052 Stream videoStream = {streamId++, 3053 StreamType::OUTPUT, 3054 static_cast<uint32_t>(videoIter.width), 3055 static_cast<uint32_t>(videoIter.height), 3056 static_cast<PixelFormat>(videoIter.format), 3057 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, 3058 0, 3059 StreamRotation::ROTATION_0}; 3060 Stream blobStream = {streamId++, 3061 StreamType::OUTPUT, 3062 static_cast<uint32_t>(blobIter.width), 3063 static_cast<uint32_t>(blobIter.height), 3064 static_cast<PixelFormat>(blobIter.format), 3065 GRALLOC1_CONSUMER_USAGE_CPU_READ, 3066 0, 3067 StreamRotation::ROTATION_0}; 3068 ::android::hardware::hidl_vec<Stream> streams = {videoStream, blobStream}; 3069 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 3070 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 3071 if (session3_4 != nullptr) { 3072 ret = session3_4->configureStreams_3_4(config, 3073 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 3074 ASSERT_EQ(Status::OK, s); 3075 ASSERT_EQ(2u, halConfig.streams.size()); 3076 }); 3077 } else if (session3_3 != nullptr) { 3078 ret = session3_3->configureStreams_3_3(config.v3_2, 3079 [](Status s, device::V3_3::HalStreamConfiguration halConfig) { 3080 ASSERT_EQ(Status::OK, s); 3081 ASSERT_EQ(2u, halConfig.streams.size()); 3082 }); 3083 } else { 3084 ret = session->configureStreams(config.v3_2, 3085 [](Status s, HalStreamConfiguration halConfig) { 3086 ASSERT_EQ(Status::OK, s); 3087 ASSERT_EQ(2u, halConfig.streams.size()); 3088 }); 3089 } 3090 ASSERT_TRUE(ret.isOk()); 3091 } 3092 } 3093 3094 free_camera_metadata(staticMeta); 3095 ret = session->close(); 3096 ASSERT_TRUE(ret.isOk()); 3097 } 3098} 3099 3100// Generate and verify a camera capture request 3101TEST_F(CameraHidlTest, processCaptureRequestPreview) { 3102 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3103 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3104 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3105 uint64_t bufferId = 1; 3106 uint32_t frameNumber = 1; 3107 ::android::hardware::hidl_vec<uint8_t> settings; 3108 3109 for (const auto& name : cameraDeviceNames) { 3110 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3111 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3112 continue; 3113 } else if (deviceVersion <= 0) { 3114 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3115 ADD_FAILURE(); 3116 return; 3117 } 3118 3119 Stream previewStream; 3120 HalStreamConfiguration halStreamConfig; 3121 sp<ICameraDeviceSession> session; 3122 bool supportsPartialResults = false; 3123 uint32_t partialResultCount = 0; 3124 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3125 &previewStream /*out*/, &halStreamConfig /*out*/, 3126 &supportsPartialResults /*out*/, 3127 &partialResultCount /*out*/); 3128 3129 std::shared_ptr<ResultMetadataQueue> resultQueue; 3130 auto resultQueueRet = 3131 session->getCaptureResultMetadataQueue( 3132 [&resultQueue](const auto& descriptor) { 3133 resultQueue = std::make_shared<ResultMetadataQueue>( 3134 descriptor); 3135 if (!resultQueue->isValid() || 3136 resultQueue->availableToWrite() <= 0) { 3137 ALOGE("%s: HAL returns empty result metadata fmq," 3138 " not use it", __func__); 3139 resultQueue = nullptr; 3140 // Don't use the queue onwards. 3141 } 3142 }); 3143 ASSERT_TRUE(resultQueueRet.isOk()); 3144 3145 InFlightRequest inflightReq = {1, false, supportsPartialResults, 3146 partialResultCount, resultQueue}; 3147 3148 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3149 Return<void> ret; 3150 ret = session->constructDefaultRequestSettings(reqTemplate, 3151 [&](auto status, const auto& req) { 3152 ASSERT_EQ(Status::OK, status); 3153 settings = req; 3154 }); 3155 ASSERT_TRUE(ret.isOk()); 3156 3157 sp<GraphicBuffer> gb = new GraphicBuffer( 3158 previewStream.width, previewStream.height, 3159 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, 3160 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3161 halStreamConfig.streams[0].consumerUsage)); 3162 ASSERT_NE(nullptr, gb.get()); 3163 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3164 bufferId, 3165 hidl_handle(gb->getNativeBuffer()->handle), 3166 BufferStatus::OK, 3167 nullptr, 3168 nullptr}; 3169 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; 3170 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, 3171 nullptr}; 3172 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3173 emptyInputBuffer, outputBuffers}; 3174 3175 { 3176 std::unique_lock<std::mutex> l(mLock); 3177 mInflightMap.clear(); 3178 mInflightMap.add(frameNumber, &inflightReq); 3179 } 3180 3181 Status status = Status::INTERNAL_ERROR; 3182 uint32_t numRequestProcessed = 0; 3183 hidl_vec<BufferCache> cachesToRemove; 3184 Return<void> returnStatus = session->processCaptureRequest( 3185 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3186 uint32_t n) { 3187 status = s; 3188 numRequestProcessed = n; 3189 }); 3190 ASSERT_TRUE(returnStatus.isOk()); 3191 ASSERT_EQ(Status::OK, status); 3192 ASSERT_EQ(numRequestProcessed, 1u); 3193 3194 { 3195 std::unique_lock<std::mutex> l(mLock); 3196 while (!inflightReq.errorCodeValid && 3197 ((0 < inflightReq.numBuffersLeft) || 3198 (!inflightReq.haveResultMetadata))) { 3199 auto timeout = std::chrono::system_clock::now() + 3200 std::chrono::seconds(kStreamBufferTimeoutSec); 3201 ASSERT_NE(std::cv_status::timeout, 3202 mResultCondition.wait_until(l, timeout)); 3203 } 3204 3205 ASSERT_FALSE(inflightReq.errorCodeValid); 3206 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3207 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); 3208 3209 request.frameNumber++; 3210 // Empty settings should be supported after the first call 3211 // for repeating requests. 3212 request.settings.setToExternal(nullptr, 0, true); 3213 // The buffer has been registered to HAL by bufferId, so per 3214 // API contract we should send a null handle for this buffer 3215 request.outputBuffers[0].buffer = nullptr; 3216 mInflightMap.clear(); 3217 inflightReq = {1, false, supportsPartialResults, partialResultCount, 3218 resultQueue}; 3219 mInflightMap.add(request.frameNumber, &inflightReq); 3220 } 3221 3222 returnStatus = session->processCaptureRequest( 3223 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3224 uint32_t n) { 3225 status = s; 3226 numRequestProcessed = n; 3227 }); 3228 ASSERT_TRUE(returnStatus.isOk()); 3229 ASSERT_EQ(Status::OK, status); 3230 ASSERT_EQ(numRequestProcessed, 1u); 3231 3232 { 3233 std::unique_lock<std::mutex> l(mLock); 3234 while (!inflightReq.errorCodeValid && 3235 ((0 < inflightReq.numBuffersLeft) || 3236 (!inflightReq.haveResultMetadata))) { 3237 auto timeout = std::chrono::system_clock::now() + 3238 std::chrono::seconds(kStreamBufferTimeoutSec); 3239 ASSERT_NE(std::cv_status::timeout, 3240 mResultCondition.wait_until(l, timeout)); 3241 } 3242 3243 ASSERT_FALSE(inflightReq.errorCodeValid); 3244 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3245 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); 3246 } 3247 3248 ret = session->close(); 3249 ASSERT_TRUE(ret.isOk()); 3250 } 3251} 3252 3253// Test whether an incorrect capture request with missing settings will 3254// be reported correctly. 3255TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) { 3256 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3257 std::vector<AvailableStream> outputPreviewStreams; 3258 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3259 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3260 uint64_t bufferId = 1; 3261 uint32_t frameNumber = 1; 3262 ::android::hardware::hidl_vec<uint8_t> settings; 3263 3264 for (const auto& name : cameraDeviceNames) { 3265 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3266 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3267 continue; 3268 } else if (deviceVersion <= 0) { 3269 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3270 ADD_FAILURE(); 3271 return; 3272 } 3273 3274 Stream previewStream; 3275 HalStreamConfiguration halStreamConfig; 3276 sp<ICameraDeviceSession> session; 3277 bool supportsPartialResults = false; 3278 uint32_t partialResultCount = 0; 3279 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3280 &previewStream /*out*/, &halStreamConfig /*out*/, 3281 &supportsPartialResults /*out*/, 3282 &partialResultCount /*out*/); 3283 3284 sp<GraphicBuffer> gb = new GraphicBuffer( 3285 previewStream.width, previewStream.height, 3286 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, 3287 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3288 halStreamConfig.streams[0].consumerUsage)); 3289 3290 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3291 bufferId, 3292 hidl_handle(gb->getNativeBuffer()->handle), 3293 BufferStatus::OK, 3294 nullptr, 3295 nullptr}; 3296 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; 3297 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, 3298 nullptr}; 3299 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3300 emptyInputBuffer, outputBuffers}; 3301 3302 // Settings were not correctly initialized, we should fail here 3303 Status status = Status::OK; 3304 uint32_t numRequestProcessed = 0; 3305 hidl_vec<BufferCache> cachesToRemove; 3306 Return<void> ret = session->processCaptureRequest( 3307 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3308 uint32_t n) { 3309 status = s; 3310 numRequestProcessed = n; 3311 }); 3312 ASSERT_TRUE(ret.isOk()); 3313 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); 3314 ASSERT_EQ(numRequestProcessed, 0u); 3315 3316 ret = session->close(); 3317 ASSERT_TRUE(ret.isOk()); 3318 } 3319} 3320 3321// Check whether an invalid capture request with missing output buffers 3322// will be reported correctly. 3323TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) { 3324 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3325 std::vector<AvailableStream> outputBlobStreams; 3326 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3327 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3328 uint32_t frameNumber = 1; 3329 ::android::hardware::hidl_vec<uint8_t> settings; 3330 3331 for (const auto& name : cameraDeviceNames) { 3332 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3333 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3334 continue; 3335 } else if (deviceVersion <= 0) { 3336 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3337 ADD_FAILURE(); 3338 return; 3339 } 3340 3341 Stream previewStream; 3342 HalStreamConfiguration halStreamConfig; 3343 sp<ICameraDeviceSession> session; 3344 bool supportsPartialResults = false; 3345 uint32_t partialResultCount = 0; 3346 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3347 &previewStream /*out*/, &halStreamConfig /*out*/, 3348 &supportsPartialResults /*out*/, 3349 &partialResultCount /*out*/); 3350 3351 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3352 Return<void> ret; 3353 ret = session->constructDefaultRequestSettings(reqTemplate, 3354 [&](auto status, const auto& req) { 3355 ASSERT_EQ(Status::OK, status); 3356 settings = req; 3357 }); 3358 ASSERT_TRUE(ret.isOk()); 3359 3360 ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers; 3361 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, 3362 nullptr}; 3363 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3364 emptyInputBuffer, emptyOutputBuffers}; 3365 3366 // Output buffers are missing, we should fail here 3367 Status status = Status::OK; 3368 uint32_t numRequestProcessed = 0; 3369 hidl_vec<BufferCache> cachesToRemove; 3370 ret = session->processCaptureRequest( 3371 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3372 uint32_t n) { 3373 status = s; 3374 numRequestProcessed = n; 3375 }); 3376 ASSERT_TRUE(ret.isOk()); 3377 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); 3378 ASSERT_EQ(numRequestProcessed, 0u); 3379 3380 ret = session->close(); 3381 ASSERT_TRUE(ret.isOk()); 3382 } 3383} 3384 3385// Generate, trigger and flush a preview request 3386TEST_F(CameraHidlTest, flushPreviewRequest) { 3387 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3388 std::vector<AvailableStream> outputPreviewStreams; 3389 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3390 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3391 uint64_t bufferId = 1; 3392 uint32_t frameNumber = 1; 3393 ::android::hardware::hidl_vec<uint8_t> settings; 3394 3395 for (const auto& name : cameraDeviceNames) { 3396 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3397 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3398 continue; 3399 } else if (deviceVersion <= 0) { 3400 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3401 ADD_FAILURE(); 3402 return; 3403 } 3404 3405 Stream previewStream; 3406 HalStreamConfiguration halStreamConfig; 3407 sp<ICameraDeviceSession> session; 3408 bool supportsPartialResults = false; 3409 uint32_t partialResultCount = 0; 3410 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3411 &previewStream /*out*/, &halStreamConfig /*out*/, 3412 &supportsPartialResults /*out*/, 3413 &partialResultCount /*out*/); 3414 3415 std::shared_ptr<ResultMetadataQueue> resultQueue; 3416 auto resultQueueRet = 3417 session->getCaptureResultMetadataQueue( 3418 [&resultQueue](const auto& descriptor) { 3419 resultQueue = std::make_shared<ResultMetadataQueue>( 3420 descriptor); 3421 if (!resultQueue->isValid() || 3422 resultQueue->availableToWrite() <= 0) { 3423 ALOGE("%s: HAL returns empty result metadata fmq," 3424 " not use it", __func__); 3425 resultQueue = nullptr; 3426 // Don't use the queue onwards. 3427 } 3428 }); 3429 ASSERT_TRUE(resultQueueRet.isOk()); 3430 3431 InFlightRequest inflightReq = {1, false, supportsPartialResults, 3432 partialResultCount, resultQueue}; 3433 RequestTemplate reqTemplate = RequestTemplate::PREVIEW; 3434 Return<void> ret; 3435 ret = session->constructDefaultRequestSettings(reqTemplate, 3436 [&](auto status, const auto& req) { 3437 ASSERT_EQ(Status::OK, status); 3438 settings = req; 3439 }); 3440 ASSERT_TRUE(ret.isOk()); 3441 3442 sp<GraphicBuffer> gb = new GraphicBuffer( 3443 previewStream.width, previewStream.height, 3444 static_cast<int32_t>(halStreamConfig.streams[0].overrideFormat), 1, 3445 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage, 3446 halStreamConfig.streams[0].consumerUsage)); 3447 ASSERT_NE(nullptr, gb.get()); 3448 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id, 3449 bufferId, 3450 hidl_handle(gb->getNativeBuffer()->handle), 3451 BufferStatus::OK, 3452 nullptr, 3453 nullptr}; 3454 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer}; 3455 const StreamBuffer emptyInputBuffer = {-1, 0, nullptr, 3456 BufferStatus::ERROR, nullptr, nullptr}; 3457 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, 3458 emptyInputBuffer, outputBuffers}; 3459 3460 { 3461 std::unique_lock<std::mutex> l(mLock); 3462 mInflightMap.clear(); 3463 mInflightMap.add(frameNumber, &inflightReq); 3464 } 3465 3466 Status status = Status::INTERNAL_ERROR; 3467 uint32_t numRequestProcessed = 0; 3468 hidl_vec<BufferCache> cachesToRemove; 3469 ret = session->processCaptureRequest( 3470 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, 3471 uint32_t n) { 3472 status = s; 3473 numRequestProcessed = n; 3474 }); 3475 3476 ASSERT_TRUE(ret.isOk()); 3477 ASSERT_EQ(Status::OK, status); 3478 ASSERT_EQ(numRequestProcessed, 1u); 3479 // Flush before waiting for request to complete. 3480 Return<Status> returnStatus = session->flush(); 3481 ASSERT_TRUE(returnStatus.isOk()); 3482 ASSERT_EQ(Status::OK, returnStatus); 3483 3484 { 3485 std::unique_lock<std::mutex> l(mLock); 3486 while (!inflightReq.errorCodeValid && 3487 ((0 < inflightReq.numBuffersLeft) || 3488 (!inflightReq.haveResultMetadata))) { 3489 auto timeout = std::chrono::system_clock::now() + 3490 std::chrono::seconds(kStreamBufferTimeoutSec); 3491 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, 3492 timeout)); 3493 } 3494 3495 if (!inflightReq.errorCodeValid) { 3496 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u); 3497 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId); 3498 } else { 3499 switch (inflightReq.errorCode) { 3500 case ErrorCode::ERROR_REQUEST: 3501 case ErrorCode::ERROR_RESULT: 3502 case ErrorCode::ERROR_BUFFER: 3503 // Expected 3504 break; 3505 case ErrorCode::ERROR_DEVICE: 3506 default: 3507 FAIL() << "Unexpected error:" 3508 << static_cast<uint32_t>(inflightReq.errorCode); 3509 } 3510 } 3511 3512 ret = session->close(); 3513 ASSERT_TRUE(ret.isOk()); 3514 } 3515 } 3516} 3517 3518// Verify that camera flushes correctly without any pending requests. 3519TEST_F(CameraHidlTest, flushEmpty) { 3520 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider); 3521 std::vector<AvailableStream> outputPreviewStreams; 3522 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, 3523 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3524 3525 for (const auto& name : cameraDeviceNames) { 3526 int deviceVersion = getCameraDeviceVersion(name, mProviderType); 3527 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) { 3528 continue; 3529 } else if (deviceVersion <= 0) { 3530 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); 3531 ADD_FAILURE(); 3532 return; 3533 } 3534 3535 Stream previewStream; 3536 HalStreamConfiguration halStreamConfig; 3537 sp<ICameraDeviceSession> session; 3538 bool supportsPartialResults = false; 3539 uint32_t partialResultCount = 0; 3540 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/, 3541 &previewStream /*out*/, &halStreamConfig /*out*/, 3542 &supportsPartialResults /*out*/, 3543 &partialResultCount /*out*/); 3544 3545 Return<Status> returnStatus = session->flush(); 3546 ASSERT_TRUE(returnStatus.isOk()); 3547 ASSERT_EQ(Status::OK, returnStatus); 3548 3549 { 3550 std::unique_lock<std::mutex> l(mLock); 3551 auto timeout = std::chrono::system_clock::now() + 3552 std::chrono::milliseconds(kEmptyFlushTimeoutMSec); 3553 ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout)); 3554 } 3555 3556 Return<void> ret = session->close(); 3557 ASSERT_TRUE(ret.isOk()); 3558 } 3559} 3560 3561// Retrieve all valid output stream resolutions from the camera 3562// static characteristics. 3563Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta, 3564 std::vector<AvailableStream> &outputStreams, 3565 const AvailableStream *threshold) { 3566 if (nullptr == staticMeta) { 3567 return Status::ILLEGAL_ARGUMENT; 3568 } 3569 3570 camera_metadata_ro_entry entry; 3571 int rc = find_camera_metadata_ro_entry(staticMeta, 3572 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry); 3573 if ((0 != rc) || (0 != (entry.count % 4))) { 3574 return Status::ILLEGAL_ARGUMENT; 3575 } 3576 3577 for (size_t i = 0; i < entry.count; i+=4) { 3578 if (ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT == 3579 entry.data.i32[i + 3]) { 3580 if(nullptr == threshold) { 3581 AvailableStream s = {entry.data.i32[i+1], 3582 entry.data.i32[i+2], entry.data.i32[i]}; 3583 outputStreams.push_back(s); 3584 } else { 3585 if ((threshold->format == entry.data.i32[i]) && 3586 (threshold->width >= entry.data.i32[i+1]) && 3587 (threshold->height >= entry.data.i32[i+2])) { 3588 AvailableStream s = {entry.data.i32[i+1], 3589 entry.data.i32[i+2], threshold->format}; 3590 outputStreams.push_back(s); 3591 } 3592 } 3593 } 3594 3595 } 3596 3597 return Status::OK; 3598} 3599 3600// Check if constrained mode is supported by using the static 3601// camera characteristics. 3602Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) { 3603 Status ret = Status::METHOD_NOT_SUPPORTED; 3604 if (nullptr == staticMeta) { 3605 return Status::ILLEGAL_ARGUMENT; 3606 } 3607 3608 camera_metadata_ro_entry entry; 3609 int rc = find_camera_metadata_ro_entry(staticMeta, 3610 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 3611 if (0 != rc) { 3612 return Status::ILLEGAL_ARGUMENT; 3613 } 3614 3615 for (size_t i = 0; i < entry.count; i++) { 3616 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO == 3617 entry.data.u8[i]) { 3618 ret = Status::OK; 3619 break; 3620 } 3621 } 3622 3623 return ret; 3624} 3625 3626// Pick the largest supported HFR mode from the static camera 3627// characteristics. 3628Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta, 3629 AvailableStream &hfrStream) { 3630 if (nullptr == staticMeta) { 3631 return Status::ILLEGAL_ARGUMENT; 3632 } 3633 3634 camera_metadata_ro_entry entry; 3635 int rc = find_camera_metadata_ro_entry(staticMeta, 3636 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry); 3637 if (0 != rc) { 3638 return Status::METHOD_NOT_SUPPORTED; 3639 } else if (0 != (entry.count % 5)) { 3640 return Status::ILLEGAL_ARGUMENT; 3641 } 3642 3643 hfrStream = {0, 0, 3644 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)}; 3645 for (size_t i = 0; i < entry.count; i+=5) { 3646 int32_t w = entry.data.i32[i]; 3647 int32_t h = entry.data.i32[i+1]; 3648 if ((hfrStream.width * hfrStream.height) < (w *h)) { 3649 hfrStream.width = w; 3650 hfrStream.height = h; 3651 } 3652 } 3653 3654 return Status::OK; 3655} 3656 3657// Check whether ZSL is available using the static camera 3658// characteristics. 3659Status CameraHidlTest::isZSLModeAvailable(camera_metadata_t *staticMeta) { 3660 Status ret = Status::METHOD_NOT_SUPPORTED; 3661 if (nullptr == staticMeta) { 3662 return Status::ILLEGAL_ARGUMENT; 3663 } 3664 3665 camera_metadata_ro_entry entry; 3666 int rc = find_camera_metadata_ro_entry(staticMeta, 3667 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); 3668 if (0 != rc) { 3669 return Status::ILLEGAL_ARGUMENT; 3670 } 3671 3672 for (size_t i = 0; i < entry.count; i++) { 3673 if ((ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING == 3674 entry.data.u8[i]) || 3675 (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING == 3676 entry.data.u8[i]) ){ 3677 ret = Status::OK; 3678 break; 3679 } 3680 } 3681 3682 return ret; 3683} 3684 3685// Retrieve the reprocess input-output format map from the static 3686// camera characteristics. 3687Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta, 3688 std::vector<AvailableZSLInputOutput> &inputOutputMap) { 3689 if (nullptr == staticMeta) { 3690 return Status::ILLEGAL_ARGUMENT; 3691 } 3692 3693 camera_metadata_ro_entry entry; 3694 int rc = find_camera_metadata_ro_entry(staticMeta, 3695 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry); 3696 if ((0 != rc) || (0 >= entry.count)) { 3697 return Status::ILLEGAL_ARGUMENT; 3698 } 3699 3700 const int32_t* contents = &entry.data.i32[0]; 3701 for (size_t i = 0; i < entry.count; ) { 3702 int32_t inputFormat = contents[i++]; 3703 int32_t length = contents[i++]; 3704 for (int32_t j = 0; j < length; j++) { 3705 int32_t outputFormat = contents[i+j]; 3706 AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat}; 3707 inputOutputMap.push_back(zslEntry); 3708 } 3709 i += length; 3710 } 3711 3712 return Status::OK; 3713} 3714 3715// Search for the largest stream size for a given format. 3716Status CameraHidlTest::findLargestSize( 3717 const std::vector<AvailableStream> &streamSizes, int32_t format, 3718 AvailableStream &result) { 3719 result = {0, 0, 0}; 3720 for (auto &iter : streamSizes) { 3721 if (format == iter.format) { 3722 if ((result.width * result.height) < (iter.width * iter.height)) { 3723 result = iter; 3724 } 3725 } 3726 } 3727 3728 return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT; 3729} 3730 3731// Check whether the camera device supports specific focus mode. 3732Status CameraHidlTest::isAutoFocusModeAvailable( 3733 CameraParameters &cameraParams, 3734 const char *mode) { 3735 ::android::String8 focusModes(cameraParams.get( 3736 CameraParameters::KEY_SUPPORTED_FOCUS_MODES)); 3737 if (focusModes.contains(mode)) { 3738 return Status::OK; 3739 } 3740 3741 return Status::METHOD_NOT_SUPPORTED; 3742} 3743 3744// Open a device session and configure a preview stream. 3745void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion, 3746 sp<ICameraProvider> provider, 3747 const AvailableStream *previewThreshold, 3748 sp<ICameraDeviceSession> *session /*out*/, 3749 Stream *previewStream /*out*/, 3750 HalStreamConfiguration *halStreamConfig /*out*/, 3751 bool *supportsPartialResults /*out*/, 3752 uint32_t *partialResultCount /*out*/) { 3753 ASSERT_NE(nullptr, session); 3754 ASSERT_NE(nullptr, previewStream); 3755 ASSERT_NE(nullptr, halStreamConfig); 3756 ASSERT_NE(nullptr, supportsPartialResults); 3757 ASSERT_NE(nullptr, partialResultCount); 3758 3759 std::vector<AvailableStream> outputPreviewStreams; 3760 ::android::sp<ICameraDevice> device3_x; 3761 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 3762 Return<void> ret; 3763 ret = provider->getCameraDeviceInterface_V3_x( 3764 name, 3765 [&](auto status, const auto& device) { 3766 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 3767 (int)status); 3768 ASSERT_EQ(Status::OK, status); 3769 ASSERT_NE(device, nullptr); 3770 device3_x = device; 3771 }); 3772 ASSERT_TRUE(ret.isOk()); 3773 3774 sp<DeviceCb> cb = new DeviceCb(this); 3775 ret = device3_x->open( 3776 cb, 3777 [&](auto status, const auto& newSession) { 3778 ALOGI("device::open returns status:%d", (int)status); 3779 ASSERT_EQ(Status::OK, status); 3780 ASSERT_NE(newSession, nullptr); 3781 *session = newSession; 3782 }); 3783 ASSERT_TRUE(ret.isOk()); 3784 3785 sp<device::V3_3::ICameraDeviceSession> session3_3; 3786 sp<device::V3_4::ICameraDeviceSession> session3_4; 3787 castSession(*session, deviceVersion, &session3_3, &session3_4); 3788 3789 camera_metadata_t *staticMeta; 3790 ret = device3_x->getCameraCharacteristics([&] (Status s, 3791 CameraMetadata metadata) { 3792 ASSERT_EQ(Status::OK, s); 3793 staticMeta = clone_camera_metadata( 3794 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 3795 ASSERT_NE(nullptr, staticMeta); 3796 }); 3797 ASSERT_TRUE(ret.isOk()); 3798 3799 camera_metadata_ro_entry entry; 3800 auto status = find_camera_metadata_ro_entry(staticMeta, 3801 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry); 3802 if ((0 == status) && (entry.count > 0)) { 3803 *partialResultCount = entry.data.i32[0]; 3804 *supportsPartialResults = (*partialResultCount > 1); 3805 } 3806 3807 outputPreviewStreams.clear(); 3808 auto rc = getAvailableOutputStreams(staticMeta, 3809 outputPreviewStreams, previewThreshold); 3810 free_camera_metadata(staticMeta); 3811 ASSERT_EQ(Status::OK, rc); 3812 ASSERT_FALSE(outputPreviewStreams.empty()); 3813 3814 *previewStream = {0, StreamType::OUTPUT, 3815 static_cast<uint32_t> (outputPreviewStreams[0].width), 3816 static_cast<uint32_t> (outputPreviewStreams[0].height), 3817 static_cast<PixelFormat> (outputPreviewStreams[0].format), 3818 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0}; 3819 ::android::hardware::hidl_vec<Stream> streams = {*previewStream}; 3820 ::android::hardware::camera::device::V3_4::StreamConfiguration config; 3821 config.v3_2 = {streams, StreamConfigurationMode::NORMAL_MODE}; 3822 if (session3_4 != nullptr) { 3823 ret = session3_4->configureStreams_3_4(config, 3824 [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) { 3825 ASSERT_EQ(Status::OK, s); 3826 ASSERT_EQ(1u, halConfig.streams.size()); 3827 halStreamConfig->streams.resize(halConfig.streams.size()); 3828 for (size_t i = 0; i < halConfig.streams.size(); i++) { 3829 halStreamConfig->streams[i] = halConfig.streams[i].v3_2; 3830 } 3831 }); 3832 } else if (session3_3 != nullptr) { 3833 ret = session3_3->configureStreams_3_3(config.v3_2, 3834 [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) { 3835 ASSERT_EQ(Status::OK, s); 3836 ASSERT_EQ(1u, halConfig.streams.size()); 3837 halStreamConfig->streams.resize(halConfig.streams.size()); 3838 for (size_t i = 0; i < halConfig.streams.size(); i++) { 3839 halStreamConfig->streams[i] = halConfig.streams[i].v3_2; 3840 } 3841 }); 3842 } else { 3843 ret = (*session)->configureStreams(config.v3_2, 3844 [&] (Status s, HalStreamConfiguration halConfig) { 3845 ASSERT_EQ(Status::OK, s); 3846 ASSERT_EQ(1u, halConfig.streams.size()); 3847 *halStreamConfig = halConfig; 3848 }); 3849 } 3850 ASSERT_TRUE(ret.isOk()); 3851} 3852 3853//Cast camera device session to corresponding version 3854void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion, 3855 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/, 3856 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/) { 3857 ASSERT_NE(nullptr, session3_3); 3858 ASSERT_NE(nullptr, session3_4); 3859 3860 switch (deviceVersion) { 3861 case CAMERA_DEVICE_API_VERSION_3_4: { 3862 auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session); 3863 ASSERT_TRUE(castResult.isOk()); 3864 *session3_4 = castResult; 3865 break; 3866 } 3867 case CAMERA_DEVICE_API_VERSION_3_3: { 3868 auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session); 3869 ASSERT_TRUE(castResult.isOk()); 3870 *session3_3 = castResult; 3871 break; 3872 } 3873 default: 3874 //no-op 3875 return; 3876 } 3877} 3878 3879// Open a device session with empty callbacks and return static metadata. 3880void CameraHidlTest::openEmptyDeviceSession(const std::string &name, 3881 sp<ICameraProvider> provider, 3882 sp<ICameraDeviceSession> *session /*out*/, 3883 camera_metadata_t **staticMeta /*out*/) { 3884 ASSERT_NE(nullptr, session); 3885 ASSERT_NE(nullptr, staticMeta); 3886 3887 ::android::sp<ICameraDevice> device3_x; 3888 ALOGI("configureStreams: Testing camera device %s", name.c_str()); 3889 Return<void> ret; 3890 ret = provider->getCameraDeviceInterface_V3_x( 3891 name, 3892 [&](auto status, const auto& device) { 3893 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", 3894 (int)status); 3895 ASSERT_EQ(Status::OK, status); 3896 ASSERT_NE(device, nullptr); 3897 device3_x = device; 3898 }); 3899 ASSERT_TRUE(ret.isOk()); 3900 3901 sp<EmptyDeviceCb> cb = new EmptyDeviceCb(); 3902 ret = device3_x->open(cb, [&](auto status, const auto& newSession) { 3903 ALOGI("device::open returns status:%d", (int)status); 3904 ASSERT_EQ(Status::OK, status); 3905 ASSERT_NE(newSession, nullptr); 3906 *session = newSession; 3907 }); 3908 ASSERT_TRUE(ret.isOk()); 3909 3910 ret = device3_x->getCameraCharacteristics([&] (Status s, 3911 CameraMetadata metadata) { 3912 ASSERT_EQ(Status::OK, s); 3913 *staticMeta = clone_camera_metadata( 3914 reinterpret_cast<const camera_metadata_t*>(metadata.data())); 3915 ASSERT_NE(nullptr, *staticMeta); 3916 }); 3917 ASSERT_TRUE(ret.isOk()); 3918} 3919 3920// Open a particular camera device. 3921void CameraHidlTest::openCameraDevice(const std::string &name, 3922 sp<ICameraProvider> provider, 3923 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) { 3924 ASSERT_TRUE(nullptr != device1); 3925 3926 Return<void> ret; 3927 ret = provider->getCameraDeviceInterface_V1_x( 3928 name, 3929 [&](auto status, const auto& device) { 3930 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", 3931 (int)status); 3932 ASSERT_EQ(Status::OK, status); 3933 ASSERT_NE(device, nullptr); 3934 *device1 = device; 3935 }); 3936 ASSERT_TRUE(ret.isOk()); 3937 3938 sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this); 3939 Return<Status> returnStatus = (*device1)->open(deviceCb); 3940 ASSERT_TRUE(returnStatus.isOk()); 3941 ASSERT_EQ(Status::OK, returnStatus); 3942} 3943 3944// Initialize and configure a preview window. 3945void CameraHidlTest::setupPreviewWindow( 3946 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 3947 sp<BufferItemConsumer> *bufferItemConsumer /*out*/, 3948 sp<BufferItemHander> *bufferHandler /*out*/) { 3949 ASSERT_NE(nullptr, device.get()); 3950 ASSERT_NE(nullptr, bufferItemConsumer); 3951 ASSERT_NE(nullptr, bufferHandler); 3952 3953 sp<IGraphicBufferProducer> producer; 3954 sp<IGraphicBufferConsumer> consumer; 3955 BufferQueue::createBufferQueue(&producer, &consumer); 3956 *bufferItemConsumer = new BufferItemConsumer(consumer, 3957 GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags 3958 ASSERT_NE(nullptr, (*bufferItemConsumer).get()); 3959 *bufferHandler = new BufferItemHander(*bufferItemConsumer); 3960 ASSERT_NE(nullptr, (*bufferHandler).get()); 3961 (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler); 3962 sp<Surface> surface = new Surface(producer); 3963 sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface); 3964 3965 auto rc = device->setPreviewWindow(previewCb); 3966 ASSERT_TRUE(rc.isOk()); 3967 ASSERT_EQ(Status::OK, rc); 3968} 3969 3970// Stop camera preview and close camera. 3971void CameraHidlTest::stopPreviewAndClose( 3972 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3973 Return<void> ret = device->stopPreview(); 3974 ASSERT_TRUE(ret.isOk()); 3975 3976 ret = device->close(); 3977 ASSERT_TRUE(ret.isOk()); 3978} 3979 3980// Enable a specific camera message type. 3981void CameraHidlTest::enableMsgType(unsigned int msgType, 3982 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3983 Return<void> ret = device->enableMsgType(msgType); 3984 ASSERT_TRUE(ret.isOk()); 3985 3986 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType); 3987 ASSERT_TRUE(returnBoolStatus.isOk()); 3988 ASSERT_TRUE(returnBoolStatus); 3989} 3990 3991// Disable a specific camera message type. 3992void CameraHidlTest::disableMsgType(unsigned int msgType, 3993 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 3994 Return<void> ret = device->disableMsgType(msgType); 3995 ASSERT_TRUE(ret.isOk()); 3996 3997 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType); 3998 ASSERT_TRUE(returnBoolStatus.isOk()); 3999 ASSERT_FALSE(returnBoolStatus); 4000} 4001 4002// Wait until a specific frame notification arrives. 4003void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame, 4004 std::unique_lock<std::mutex> &l) { 4005 while (msgFrame != mDataMessageTypeReceived) { 4006 auto timeout = std::chrono::system_clock::now() + 4007 std::chrono::seconds(kStreamBufferTimeoutSec); 4008 ASSERT_NE(std::cv_status::timeout, 4009 mResultCondition.wait_until(l, timeout)); 4010 } 4011} 4012 4013// Start preview on a particular camera device 4014void CameraHidlTest::startPreview( 4015 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) { 4016 Return<Status> returnStatus = device->startPreview(); 4017 ASSERT_TRUE(returnStatus.isOk()); 4018 ASSERT_EQ(Status::OK, returnStatus); 4019} 4020 4021// Retrieve camera parameters. 4022void CameraHidlTest::getParameters( 4023 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 4024 CameraParameters *cameraParams /*out*/) { 4025 ASSERT_NE(nullptr, cameraParams); 4026 4027 Return<void> ret; 4028 ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) { 4029 ASSERT_FALSE(params.empty()); 4030 ::android::String8 paramString(params.c_str()); 4031 (*cameraParams).unflatten(paramString); 4032 }); 4033 ASSERT_TRUE(ret.isOk()); 4034} 4035 4036// Set camera parameters. 4037void CameraHidlTest::setParameters( 4038 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device, 4039 const CameraParameters &cameraParams) { 4040 Return<Status> returnStatus = device->setParameters( 4041 cameraParams.flatten().string()); 4042 ASSERT_TRUE(returnStatus.isOk()); 4043 ASSERT_EQ(Status::OK, returnStatus); 4044} 4045 4046int main(int argc, char **argv) { 4047 ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance()); 4048 ::testing::InitGoogleTest(&argc, argv); 4049 CameraHidlEnvironment::Instance()->init(&argc, argv); 4050 int status = RUN_ALL_TESTS(); 4051 ALOGI("Test result = %d", status); 4052 return status; 4053} 4054