1 /*
2 * Copyright (C) 2016-2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "camera_hidl_hal_test"
18
19 #include <algorithm>
20 #include <chrono>
21 #include <mutex>
22 #include <regex>
23 #include <unordered_map>
24 #include <unordered_set>
25 #include <condition_variable>
26
27 #include <inttypes.h>
28
29 #include <android/hardware/camera/device/1.0/ICameraDevice.h>
30 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
31 #include <android/hardware/camera/device/3.5/ICameraDevice.h>
32 #include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
33 #include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
34 #include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
35 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
36 #include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
37 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
38 #include <android/hardware/camera/provider/2.5/ICameraProvider.h>
39 #include <android/hardware/camera/metadata/3.4/types.h>
40 #include <android/hidl/manager/1.0/IServiceManager.h>
41 #include <binder/MemoryHeapBase.h>
42 #include <CameraMetadata.h>
43 #include <CameraParameters.h>
44 #include <cutils/properties.h>
45 #include <fmq/MessageQueue.h>
46 #include <grallocusage/GrallocUsageConversion.h>
47 #include <gui/BufferItemConsumer.h>
48 #include <gui/BufferQueue.h>
49 #include <gui/Surface.h>
50 #include <hardware/gralloc.h>
51 #include <hardware/gralloc1.h>
52 #include <system/camera.h>
53 #include <system/camera_metadata.h>
54 #include <ui/GraphicBuffer.h>
55
56 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
57 #include <android/hardware/graphics/allocator/3.0/IAllocator.h>
58 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
59 #include <android/hardware/graphics/mapper/2.0/types.h>
60 #include <android/hardware/graphics/mapper/3.0/IMapper.h>
61 #include <android/hidl/allocator/1.0/IAllocator.h>
62 #include <android/hidl/memory/1.0/IMapper.h>
63 #include <android/hidl/memory/1.0/IMemory.h>
64
65 #include <VtsHalHidlTargetTestBase.h>
66 #include <VtsHalHidlTargetTestEnvBase.h>
67
68 using namespace ::android::hardware::camera::device;
69 using ::android::hardware::Return;
70 using ::android::hardware::Void;
71 using ::android::hardware::hidl_bitfield;
72 using ::android::hardware::hidl_handle;
73 using ::android::hardware::hidl_string;
74 using ::android::hardware::hidl_vec;
75 using ::android::sp;
76 using ::android::wp;
77 using ::android::GraphicBuffer;
78 using ::android::IGraphicBufferProducer;
79 using ::android::IGraphicBufferConsumer;
80 using ::android::BufferQueue;
81 using ::android::BufferItemConsumer;
82 using ::android::Surface;
83 using ::android::hardware::graphics::common::V1_0::BufferUsage;
84 using ::android::hardware::graphics::common::V1_0::Dataspace;
85 using ::android::hardware::graphics::common::V1_0::PixelFormat;
86 using ::android::hardware::camera::common::V1_0::Status;
87 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
88 using ::android::hardware::camera::common::V1_0::TorchMode;
89 using ::android::hardware::camera::common::V1_0::TorchModeStatus;
90 using ::android::hardware::camera::common::V1_0::helper::CameraParameters;
91 using ::android::hardware::camera::common::V1_0::helper::Size;
92 using ::android::hardware::camera::provider::V2_4::ICameraProvider;
93 using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
94 using ::android::hardware::camera::device::V3_2::ICameraDevice;
95 using ::android::hardware::camera::device::V3_2::BufferCache;
96 using ::android::hardware::camera::device::V3_2::CaptureRequest;
97 using ::android::hardware::camera::device::V3_2::CaptureResult;
98 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
99 using ::android::hardware::camera::device::V3_2::NotifyMsg;
100 using ::android::hardware::camera::device::V3_2::RequestTemplate;
101 using ::android::hardware::camera::device::V3_2::StreamType;
102 using ::android::hardware::camera::device::V3_2::StreamRotation;
103 using ::android::hardware::camera::device::V3_2::StreamConfiguration;
104 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
105 using ::android::hardware::camera::device::V3_2::CameraMetadata;
106 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
107 using ::android::hardware::camera::device::V3_2::BufferStatus;
108 using ::android::hardware::camera::device::V3_2::StreamBuffer;
109 using ::android::hardware::camera::device::V3_2::MsgType;
110 using ::android::hardware::camera::device::V3_2::ErrorMsg;
111 using ::android::hardware::camera::device::V3_2::ErrorCode;
112 using ::android::hardware::camera::device::V1_0::CameraFacing;
113 using ::android::hardware::camera::device::V1_0::NotifyCallbackMsg;
114 using ::android::hardware::camera::device::V1_0::CommandType;
115 using ::android::hardware::camera::device::V1_0::DataCallbackMsg;
116 using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
117 using ::android::hardware::camera::device::V1_0::ICameraDevicePreviewCallback;
118 using ::android::hardware::camera::device::V1_0::FrameCallbackFlag;
119 using ::android::hardware::camera::device::V1_0::HandleTimestampMessage;
120 using ::android::hardware::camera::metadata::V3_4::CameraMetadataEnumAndroidSensorInfoColorFilterArrangement;
121 using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag;
122 using ::android::hardware::camera::device::V3_4::PhysicalCameraMetadata;
123 using ::android::hardware::MessageQueue;
124 using ::android::hardware::kSynchronizedReadWrite;
125 using ::android::hidl::allocator::V1_0::IAllocator;
126 using ::android::hidl::memory::V1_0::IMemory;
127 using ::android::hidl::memory::V1_0::IMapper;
128 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
129 using ::android::hidl::manager::V1_0::IServiceManager;
130
131 using namespace ::android::hardware::camera;
132
133 const uint32_t kMaxPreviewWidth = 1920;
134 const uint32_t kMaxPreviewHeight = 1080;
135 const uint32_t kMaxVideoWidth = 4096;
136 const uint32_t kMaxVideoHeight = 2160;
137 const int64_t kStreamBufferTimeoutSec = 3;
138 const int64_t kAutoFocusTimeoutSec = 5;
139 const int64_t kTorchTimeoutSec = 1;
140 const int64_t kEmptyFlushTimeoutMSec = 200;
141 const char kDumpOutput[] = "/dev/null";
142 const uint32_t kBurstFrameCount = 10;
143 const int64_t kBufferReturnTimeoutSec = 1;
144
145 struct AvailableStream {
146 int32_t width;
147 int32_t height;
148 int32_t format;
149 };
150
151 struct AvailableZSLInputOutput {
152 int32_t inputFormat;
153 int32_t outputFormat;
154 };
155
156 enum ReprocessType {
157 PRIV_REPROCESS,
158 YUV_REPROCESS,
159 };
160
161 namespace {
162 // "device@<version>/legacy/<id>"
163 const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
164 const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
165 const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
166 const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
167 const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
168 const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
169 const char *kHAL3_5 = "3.5";
170 const char *kHAL3_4 = "3.4";
171 const char *kHAL3_3 = "3.3";
172 const char *kHAL3_2 = "3.2";
173 const char *kHAL1_0 = "1.0";
174
matchDeviceName(const hidl_string & deviceName,const hidl_string & providerType,std::string * deviceVersion,std::string * cameraId)175 bool matchDeviceName(const hidl_string& deviceName,
176 const hidl_string &providerType,
177 std::string* deviceVersion,
178 std::string* cameraId) {
179 ::android::String8 pattern;
180 pattern.appendFormat(kDeviceNameRE, providerType.c_str());
181 std::regex e(pattern.string());
182 std::string deviceNameStd(deviceName.c_str());
183 std::smatch sm;
184 if (std::regex_match(deviceNameStd, sm, e)) {
185 if (deviceVersion != nullptr) {
186 *deviceVersion = sm[1];
187 }
188 if (cameraId != nullptr) {
189 *cameraId = sm[2];
190 }
191 return true;
192 }
193 return false;
194 }
195
getCameraDeviceVersion(const hidl_string & deviceName,const hidl_string & providerType)196 int getCameraDeviceVersion(const hidl_string& deviceName,
197 const hidl_string &providerType) {
198 std::string version;
199 bool match = matchDeviceName(deviceName, providerType, &version, nullptr);
200 if (!match) {
201 return -1;
202 }
203
204 if (version.compare(kHAL3_5) == 0) {
205 return CAMERA_DEVICE_API_VERSION_3_5;
206 } else if (version.compare(kHAL3_4) == 0) {
207 return CAMERA_DEVICE_API_VERSION_3_4;
208 } else if (version.compare(kHAL3_3) == 0) {
209 return CAMERA_DEVICE_API_VERSION_3_3;
210 } else if (version.compare(kHAL3_2) == 0) {
211 return CAMERA_DEVICE_API_VERSION_3_2;
212 } else if (version.compare(kHAL1_0) == 0) {
213 return CAMERA_DEVICE_API_VERSION_1_0;
214 }
215 return 0;
216 }
217
parseProviderName(const std::string & name,std::string * type,uint32_t * id)218 bool parseProviderName(const std::string& name, std::string *type /*out*/,
219 uint32_t *id /*out*/) {
220 if (!type || !id) {
221 ADD_FAILURE();
222 return false;
223 }
224
225 std::string::size_type slashIdx = name.find('/');
226 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
227 ADD_FAILURE() << "Provider name does not have / separator between type"
228 "and id";
229 return false;
230 }
231
232 std::string typeVal = name.substr(0, slashIdx);
233
234 char *endPtr;
235 errno = 0;
236 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
237 if (errno != 0) {
238 ADD_FAILURE() << "cannot parse provider id as an integer:" <<
239 name.c_str() << strerror(errno) << errno;
240 return false;
241 }
242 if (endPtr != name.c_str() + name.size()) {
243 ADD_FAILURE() << "provider id has unexpected length " << name.c_str();
244 return false;
245 }
246 if (idVal < 0) {
247 ADD_FAILURE() << "id is negative: " << name.c_str() << idVal;
248 return false;
249 }
250
251 *type = typeVal;
252 *id = static_cast<uint32_t>(idVal);
253
254 return true;
255 }
256
mapToStatus(::android::status_t s)257 Status mapToStatus(::android::status_t s) {
258 switch(s) {
259 case ::android::OK:
260 return Status::OK ;
261 case ::android::BAD_VALUE:
262 return Status::ILLEGAL_ARGUMENT ;
263 case -EBUSY:
264 return Status::CAMERA_IN_USE;
265 case -EUSERS:
266 return Status::MAX_CAMERAS_IN_USE;
267 case ::android::UNKNOWN_TRANSACTION:
268 return Status::METHOD_NOT_SUPPORTED;
269 case ::android::INVALID_OPERATION:
270 return Status::OPERATION_NOT_SUPPORTED;
271 case ::android::DEAD_OBJECT:
272 return Status::CAMERA_DISCONNECTED;
273 }
274 ALOGW("Unexpected HAL status code %d", s);
275 return Status::OPERATION_NOT_SUPPORTED;
276 }
277
getFirstApiLevel(int32_t * outApiLevel)278 void getFirstApiLevel(/*out*/int32_t* outApiLevel) {
279 int32_t firstApiLevel = property_get_int32("ro.product.first_api_level", /*default*/-1);
280 if (firstApiLevel < 0) {
281 firstApiLevel = property_get_int32("ro.build.version.sdk", /*default*/-1);
282 }
283 ASSERT_GT(firstApiLevel, 0); // first_api_level must exist
284 *outApiLevel = firstApiLevel;
285 return;
286 }
287 }
288
289 // Test environment for camera
290 class CameraHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
291 public:
292 // get the test environment singleton
Instance()293 static CameraHidlEnvironment* Instance() {
294 static CameraHidlEnvironment* instance = new CameraHidlEnvironment;
295 return instance;
296 }
297
HidlSetUp()298 virtual void HidlSetUp() override { ALOGI("SetUp CameraHidlEnvironment"); }
299
HidlTearDown()300 virtual void HidlTearDown() override { ALOGI("TearDown CameraHidlEnvironment"); }
301
registerTestServices()302 virtual void registerTestServices() override { registerTestService<ICameraProvider>(); }
303
304 private:
CameraHidlEnvironment()305 CameraHidlEnvironment() {}
306
307 GTEST_DISALLOW_COPY_AND_ASSIGN_(CameraHidlEnvironment);
308 };
309
310 struct BufferItemHander: public BufferItemConsumer::FrameAvailableListener {
BufferItemHanderBufferItemHander311 BufferItemHander(wp<BufferItemConsumer> consumer) : mConsumer(consumer) {}
312
onFrameAvailableBufferItemHander313 void onFrameAvailable(const android::BufferItem&) override {
314 sp<BufferItemConsumer> consumer = mConsumer.promote();
315 ASSERT_NE(nullptr, consumer.get());
316
317 android::BufferItem buffer;
318 ASSERT_EQ(android::OK, consumer->acquireBuffer(&buffer, 0));
319 ASSERT_EQ(android::OK, consumer->releaseBuffer(buffer));
320 }
321
322 private:
323 wp<BufferItemConsumer> mConsumer;
324 };
325
326 struct PreviewWindowCb : public ICameraDevicePreviewCallback {
PreviewWindowCbPreviewWindowCb327 PreviewWindowCb(sp<ANativeWindow> anw) : mPreviewWidth(0),
328 mPreviewHeight(0), mFormat(0), mPreviewUsage(0),
329 mPreviewSwapInterval(-1), mCrop{-1, -1, -1, -1}, mAnw(anw) {}
330
331 using dequeueBuffer_cb =
332 std::function<void(Status status, uint64_t bufferId,
333 const hidl_handle& buffer, uint32_t stride)>;
334 Return<void> dequeueBuffer(dequeueBuffer_cb _hidl_cb) override;
335
336 Return<Status> enqueueBuffer(uint64_t bufferId) override;
337
338 Return<Status> cancelBuffer(uint64_t bufferId) override;
339
340 Return<Status> setBufferCount(uint32_t count) override;
341
342 Return<Status> setBuffersGeometry(uint32_t w,
343 uint32_t h, PixelFormat format) override;
344
345 Return<Status> setCrop(int32_t left, int32_t top,
346 int32_t right, int32_t bottom) override;
347
348 Return<Status> setUsage(BufferUsage usage) override;
349
350 Return<Status> setSwapInterval(int32_t interval) override;
351
352 using getMinUndequeuedBufferCount_cb =
353 std::function<void(Status status, uint32_t count)>;
354 Return<void> getMinUndequeuedBufferCount(
355 getMinUndequeuedBufferCount_cb _hidl_cb) override;
356
357 Return<Status> setTimestamp(int64_t timestamp) override;
358
359 private:
360 struct BufferHasher {
operator ()PreviewWindowCb::BufferHasher361 size_t operator()(const buffer_handle_t& buf) const {
362 if (buf == nullptr)
363 return 0;
364
365 size_t result = 1;
366 result = 31 * result + buf->numFds;
367 for (int i = 0; i < buf->numFds; i++) {
368 result = 31 * result + buf->data[i];
369 }
370 return result;
371 }
372 };
373
374 struct BufferComparator {
operator ()PreviewWindowCb::BufferComparator375 bool operator()(const buffer_handle_t& buf1,
376 const buffer_handle_t& buf2) const {
377 if (buf1->numFds == buf2->numFds) {
378 for (int i = 0; i < buf1->numFds; i++) {
379 if (buf1->data[i] != buf2->data[i]) {
380 return false;
381 }
382 }
383 return true;
384 }
385 return false;
386 }
387 };
388
389 std::pair<bool, uint64_t> getBufferId(ANativeWindowBuffer* anb);
390 void cleanupCirculatingBuffers();
391
392 std::mutex mBufferIdMapLock; // protecting mBufferIdMap and mNextBufferId
393 typedef std::unordered_map<const buffer_handle_t, uint64_t,
394 BufferHasher, BufferComparator> BufferIdMap;
395
396 BufferIdMap mBufferIdMap; // stream ID -> per stream buffer ID map
397 std::unordered_map<uint64_t, ANativeWindowBuffer*> mReversedBufMap;
398 uint64_t mNextBufferId = 1;
399
400 uint32_t mPreviewWidth, mPreviewHeight;
401 int mFormat, mPreviewUsage;
402 int32_t mPreviewSwapInterval;
403 android_native_rect_t mCrop;
404 sp<ANativeWindow> mAnw; //Native window reference
405 };
406
getBufferId(ANativeWindowBuffer * anb)407 std::pair<bool, uint64_t> PreviewWindowCb::getBufferId(
408 ANativeWindowBuffer* anb) {
409 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
410
411 buffer_handle_t& buf = anb->handle;
412 auto it = mBufferIdMap.find(buf);
413 if (it == mBufferIdMap.end()) {
414 uint64_t bufId = mNextBufferId++;
415 mBufferIdMap[buf] = bufId;
416 mReversedBufMap[bufId] = anb;
417 return std::make_pair(true, bufId);
418 } else {
419 return std::make_pair(false, it->second);
420 }
421 }
422
cleanupCirculatingBuffers()423 void PreviewWindowCb::cleanupCirculatingBuffers() {
424 std::lock_guard<std::mutex> lock(mBufferIdMapLock);
425 mBufferIdMap.clear();
426 mReversedBufMap.clear();
427 }
428
dequeueBuffer(dequeueBuffer_cb _hidl_cb)429 Return<void> PreviewWindowCb::dequeueBuffer(dequeueBuffer_cb _hidl_cb) {
430 ANativeWindowBuffer* anb;
431 auto rc = native_window_dequeue_buffer_and_wait(mAnw.get(), &anb);
432 uint64_t bufferId = 0;
433 uint32_t stride = 0;
434 hidl_handle buf = nullptr;
435 if (rc == ::android::OK) {
436 auto pair = getBufferId(anb);
437 buf = (pair.first) ? anb->handle : nullptr;
438 bufferId = pair.second;
439 stride = anb->stride;
440 }
441
442 _hidl_cb(mapToStatus(rc), bufferId, buf, stride);
443 return Void();
444 }
445
enqueueBuffer(uint64_t bufferId)446 Return<Status> PreviewWindowCb::enqueueBuffer(uint64_t bufferId) {
447 if (mReversedBufMap.count(bufferId) == 0) {
448 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
449 return Status::ILLEGAL_ARGUMENT;
450 }
451 return mapToStatus(mAnw->queueBuffer(mAnw.get(),
452 mReversedBufMap.at(bufferId), -1));
453 }
454
cancelBuffer(uint64_t bufferId)455 Return<Status> PreviewWindowCb::cancelBuffer(uint64_t bufferId) {
456 if (mReversedBufMap.count(bufferId) == 0) {
457 ALOGE("%s: bufferId %" PRIu64 " not found", __FUNCTION__, bufferId);
458 return Status::ILLEGAL_ARGUMENT;
459 }
460 return mapToStatus(mAnw->cancelBuffer(mAnw.get(),
461 mReversedBufMap.at(bufferId), -1));
462 }
463
setBufferCount(uint32_t count)464 Return<Status> PreviewWindowCb::setBufferCount(uint32_t count) {
465 if (mAnw.get() != nullptr) {
466 // WAR for b/27039775
467 native_window_api_disconnect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
468 native_window_api_connect(mAnw.get(), NATIVE_WINDOW_API_CAMERA);
469 if (mPreviewWidth != 0) {
470 native_window_set_buffers_dimensions(mAnw.get(),
471 mPreviewWidth, mPreviewHeight);
472 native_window_set_buffers_format(mAnw.get(), mFormat);
473 }
474 if (mPreviewUsage != 0) {
475 native_window_set_usage(mAnw.get(), mPreviewUsage);
476 }
477 if (mPreviewSwapInterval >= 0) {
478 mAnw->setSwapInterval(mAnw.get(), mPreviewSwapInterval);
479 }
480 if (mCrop.left >= 0) {
481 native_window_set_crop(mAnw.get(), &(mCrop));
482 }
483 }
484
485 auto rc = native_window_set_buffer_count(mAnw.get(), count);
486 if (rc == ::android::OK) {
487 cleanupCirculatingBuffers();
488 }
489
490 return mapToStatus(rc);
491 }
492
setBuffersGeometry(uint32_t w,uint32_t h,PixelFormat format)493 Return<Status> PreviewWindowCb::setBuffersGeometry(uint32_t w, uint32_t h,
494 PixelFormat format) {
495 auto rc = native_window_set_buffers_dimensions(mAnw.get(), w, h);
496 if (rc == ::android::OK) {
497 mPreviewWidth = w;
498 mPreviewHeight = h;
499 rc = native_window_set_buffers_format(mAnw.get(),
500 static_cast<int>(format));
501 if (rc == ::android::OK) {
502 mFormat = static_cast<int>(format);
503 }
504 }
505
506 return mapToStatus(rc);
507 }
508
setCrop(int32_t left,int32_t top,int32_t right,int32_t bottom)509 Return<Status> PreviewWindowCb::setCrop(int32_t left, int32_t top,
510 int32_t right, int32_t bottom) {
511 android_native_rect_t crop = { left, top, right, bottom };
512 auto rc = native_window_set_crop(mAnw.get(), &crop);
513 if (rc == ::android::OK) {
514 mCrop = crop;
515 }
516 return mapToStatus(rc);
517 }
518
setUsage(BufferUsage usage)519 Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) {
520 auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
521 if (rc == ::android::OK) {
522 mPreviewUsage = static_cast<int>(usage);
523 }
524 return mapToStatus(rc);
525 }
526
setSwapInterval(int32_t interval)527 Return<Status> PreviewWindowCb::setSwapInterval(int32_t interval) {
528 auto rc = mAnw->setSwapInterval(mAnw.get(), interval);
529 if (rc == ::android::OK) {
530 mPreviewSwapInterval = interval;
531 }
532 return mapToStatus(rc);
533 }
534
getMinUndequeuedBufferCount(getMinUndequeuedBufferCount_cb _hidl_cb)535 Return<void> PreviewWindowCb::getMinUndequeuedBufferCount(
536 getMinUndequeuedBufferCount_cb _hidl_cb) {
537 int count = 0;
538 auto rc = mAnw->query(mAnw.get(),
539 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &count);
540 _hidl_cb(mapToStatus(rc), count);
541 return Void();
542 }
543
setTimestamp(int64_t timestamp)544 Return<Status> PreviewWindowCb::setTimestamp(int64_t timestamp) {
545 return mapToStatus(native_window_set_buffers_timestamp(mAnw.get(),
546 timestamp));
547 }
548
549 // The main test class for camera HIDL HAL.
550 class CameraHidlTest : public ::testing::VtsHalHidlTargetTestBase {
551 public:
SetUp()552 virtual void SetUp() override {
553 string service_name = CameraHidlEnvironment::Instance()->getServiceName<ICameraProvider>();
554 ALOGI("get service with name: %s", service_name.c_str());
555 mProvider = ::testing::VtsHalHidlTargetTestBase::getService<ICameraProvider>(service_name);
556 ASSERT_NE(mProvider, nullptr);
557
558 uint32_t id;
559 ASSERT_TRUE(parseProviderName(service_name, &mProviderType, &id));
560
561 castProvider(mProvider, &mProvider2_5);
562 notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
563 }
TearDown()564 virtual void TearDown() override {}
565
566 hidl_vec<hidl_string> getCameraDeviceNames(sp<ICameraProvider> provider);
567
568 struct EmptyDeviceCb : public V3_5::ICameraDeviceCallback {
processCaptureResultCameraHidlTest::EmptyDeviceCb569 virtual Return<void> processCaptureResult(
570 const hidl_vec<CaptureResult>& /*results*/) override {
571 ALOGI("processCaptureResult callback");
572 ADD_FAILURE(); // Empty callback should not reach here
573 return Void();
574 }
575
processCaptureResult_3_4CameraHidlTest::EmptyDeviceCb576 virtual Return<void> processCaptureResult_3_4(
577 const hidl_vec<V3_4::CaptureResult>& /*results*/) override {
578 ALOGI("processCaptureResult_3_4 callback");
579 ADD_FAILURE(); // Empty callback should not reach here
580 return Void();
581 }
582
notifyCameraHidlTest::EmptyDeviceCb583 virtual Return<void> notify(const hidl_vec<NotifyMsg>& /*msgs*/) override {
584 ALOGI("notify callback");
585 ADD_FAILURE(); // Empty callback should not reach here
586 return Void();
587 }
588
requestStreamBuffersCameraHidlTest::EmptyDeviceCb589 virtual Return<void> requestStreamBuffers(
590 const hidl_vec<V3_5::BufferRequest>&,
591 requestStreamBuffers_cb _hidl_cb) override {
592 ALOGI("requestStreamBuffers callback");
593 // HAL might want to request buffer after configureStreams, but tests with EmptyDeviceCb
594 // doesn't actually need to send capture requests, so just return an error.
595 hidl_vec<V3_5::StreamBufferRet> emptyBufRets;
596 _hidl_cb(V3_5::BufferRequestStatus::FAILED_UNKNOWN, emptyBufRets);
597 return Void();
598 }
599
returnStreamBuffersCameraHidlTest::EmptyDeviceCb600 virtual Return<void> returnStreamBuffers(const hidl_vec<StreamBuffer>&) override {
601 ALOGI("returnStreamBuffers");
602 ADD_FAILURE(); // Empty callback should not reach here
603 return Void();
604 }
605
606 };
607
608 struct DeviceCb : public V3_5::ICameraDeviceCallback {
DeviceCbCameraHidlTest::DeviceCb609 DeviceCb(CameraHidlTest *parent, int deviceVersion, const camera_metadata_t *staticMeta) :
610 mParent(parent), mDeviceVersion(deviceVersion) {
611 mStaticMetadata = staticMeta;
612 }
613
614 Return<void> processCaptureResult_3_4(
615 const hidl_vec<V3_4::CaptureResult>& results) override;
616 Return<void> processCaptureResult(const hidl_vec<CaptureResult>& results) override;
617 Return<void> notify(const hidl_vec<NotifyMsg>& msgs) override;
618
619 Return<void> requestStreamBuffers(
620 const hidl_vec<V3_5::BufferRequest>& bufReqs,
621 requestStreamBuffers_cb _hidl_cb) override;
622
623 Return<void> returnStreamBuffers(const hidl_vec<StreamBuffer>& buffers) override;
624
625 void setCurrentStreamConfig(const hidl_vec<V3_2::Stream>& streams,
626 const hidl_vec<V3_2::HalStream>& halStreams);
627
628 void waitForBuffersReturned();
629
630 private:
631 bool processCaptureResultLocked(const CaptureResult& results,
632 hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata);
633
634 CameraHidlTest *mParent; // Parent object
635 int mDeviceVersion;
636 android::hardware::camera::common::V1_0::helper::CameraMetadata mStaticMetadata;
637 bool hasOutstandingBuffersLocked();
638
639 /* members for requestStreamBuffers() and returnStreamBuffers()*/
640 std::mutex mLock; // protecting members below
641 bool mUseHalBufManager = false;
642 hidl_vec<V3_2::Stream> mStreams;
643 hidl_vec<V3_2::HalStream> mHalStreams;
644 uint64_t mNextBufferId = 1;
645 using OutstandingBuffers = std::unordered_map<uint64_t, hidl_handle>;
646 // size == mStreams.size(). Tracking each streams outstanding buffers
647 std::vector<OutstandingBuffers> mOutstandingBufferIds;
648 std::condition_variable mFlushedCondition;
649 };
650
651 struct TorchProviderCb : public ICameraProviderCallback {
TorchProviderCbCameraHidlTest::TorchProviderCb652 TorchProviderCb(CameraHidlTest *parent) : mParent(parent) {}
cameraDeviceStatusChangeCameraHidlTest::TorchProviderCb653 virtual Return<void> cameraDeviceStatusChange(
654 const hidl_string&, CameraDeviceStatus) override {
655 return Void();
656 }
657
torchModeStatusChangeCameraHidlTest::TorchProviderCb658 virtual Return<void> torchModeStatusChange(
659 const hidl_string&, TorchModeStatus newStatus) override {
660 std::lock_guard<std::mutex> l(mParent->mTorchLock);
661 mParent->mTorchStatus = newStatus;
662 mParent->mTorchCond.notify_one();
663 return Void();
664 }
665
666 private:
667 CameraHidlTest *mParent; // Parent object
668 };
669
670 struct Camera1DeviceCb :
671 public ::android::hardware::camera::device::V1_0::ICameraDeviceCallback {
Camera1DeviceCbCameraHidlTest::Camera1DeviceCb672 Camera1DeviceCb(CameraHidlTest *parent) : mParent(parent) {}
673
674 Return<void> notifyCallback(NotifyCallbackMsg msgType,
675 int32_t ext1, int32_t ext2) override;
676
677 Return<uint32_t> registerMemory(const hidl_handle& descriptor,
678 uint32_t bufferSize, uint32_t bufferCount) override;
679
680 Return<void> unregisterMemory(uint32_t memId) override;
681
682 Return<void> dataCallback(DataCallbackMsg msgType,
683 uint32_t data, uint32_t bufferIndex,
684 const CameraFrameMetadata& metadata) override;
685
686 Return<void> dataCallbackTimestamp(DataCallbackMsg msgType,
687 uint32_t data, uint32_t bufferIndex,
688 int64_t timestamp) override;
689
690 Return<void> handleCallbackTimestamp(DataCallbackMsg msgType,
691 const hidl_handle& frameData,uint32_t data,
692 uint32_t bufferIndex, int64_t timestamp) override;
693
694 Return<void> handleCallbackTimestampBatch(DataCallbackMsg msgType,
695 const ::android::hardware::hidl_vec<HandleTimestampMessage>& batch) override;
696
697
698 private:
699 CameraHidlTest *mParent; // Parent object
700 };
701
702 void notifyDeviceState(::android::hardware::camera::provider::V2_5::DeviceState newState);
703
704 void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
705 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
706 void setupPreviewWindow(
707 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
708 sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
709 sp<BufferItemHander> *bufferHandler /*out*/);
710 void stopPreviewAndClose(
711 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
712 void startPreview(
713 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
714 void enableMsgType(unsigned int msgType,
715 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
716 void disableMsgType(unsigned int msgType,
717 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device);
718 void getParameters(
719 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
720 CameraParameters *cameraParams /*out*/);
721 void setParameters(
722 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
723 const CameraParameters &cameraParams);
724 void allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage,
725 PixelFormat format, hidl_handle *buffer_handle /*out*/);
726 void waitForFrameLocked(DataCallbackMsg msgFrame,
727 std::unique_lock<std::mutex> &l);
728 void openEmptyDeviceSession(const std::string &name,
729 sp<ICameraProvider> provider,
730 sp<ICameraDeviceSession> *session /*out*/,
731 camera_metadata_t **staticMeta /*out*/,
732 ::android::sp<ICameraDevice> *device = nullptr/*out*/);
733 void castProvider(const sp<provider::V2_4::ICameraProvider> &provider,
734 sp<provider::V2_5::ICameraProvider> *provider2_5 /*out*/);
735 void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
736 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
737 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
738 sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/);
739 void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion,
740 sp<device::V3_5::ICameraDevice> *device3_5/*out*/);
741 void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
742 StreamConfigurationMode configMode,
743 ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2,
744 ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4,
745 ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5,
746 uint32_t jpegBufferSize = 0);
747
748 void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
749 sp<ICameraProvider> provider,
750 const AvailableStream *previewThreshold,
751 const std::unordered_set<std::string>& physicalIds,
752 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
753 sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
754 V3_2::Stream* previewStream /*out*/,
755 device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/,
756 bool *supportsPartialResults /*out*/,
757 uint32_t *partialResultCount /*out*/,
758 bool *useHalBufManager /*out*/,
759 sp<DeviceCb> *cb /*out*/,
760 uint32_t streamConfigCounter = 0,
761 bool allowUnsupport = false);
762 void configurePreviewStream(const std::string &name, int32_t deviceVersion,
763 sp<ICameraProvider> provider,
764 const AvailableStream *previewThreshold,
765 sp<ICameraDeviceSession> *session /*out*/,
766 V3_2::Stream *previewStream /*out*/,
767 HalStreamConfiguration *halStreamConfig /*out*/,
768 bool *supportsPartialResults /*out*/,
769 uint32_t *partialResultCount /*out*/,
770 bool *useHalBufManager /*out*/,
771 sp<DeviceCb> *cb /*out*/,
772 uint32_t streamConfigCounter = 0);
773
774 void verifyLogicalCameraMetadata(const std::string& cameraName,
775 const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
776 const CameraMetadata& chars, int deviceVersion,
777 const hidl_vec<hidl_string>& deviceNames);
778 void verifyCameraCharacteristics(Status status, const CameraMetadata& chars);
779 void verifyRecommendedConfigs(const CameraMetadata& metadata);
780 void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion);
781 void verifyMonochromeCameraResult(
782 const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata);
783 void verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
784 const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
785 bool expectedStatus, bool expectStreamCombQuery);
786 void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
787 const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata);
788
789 void verifyBuffersReturned(sp<device::V3_2::ICameraDeviceSession> session,
790 int deviceVerison, int32_t streamId, sp<DeviceCb> cb,
791 uint32_t streamConfigCounter = 0);
792
793 void verifyBuffersReturned(sp<device::V3_4::ICameraDeviceSession> session,
794 hidl_vec<int32_t> streamIds, sp<DeviceCb> cb,
795 uint32_t streamConfigCounter = 0);
796
797 void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,
798 camera_metadata* oldSessionParams, camera_metadata* newSessionParams);
799
800 bool isDepthOnly(camera_metadata_t* staticMeta);
801
802 static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
803 std::vector<AvailableStream> &outputStreams,
804 const AvailableStream *threshold = nullptr);
805 static Status getJpegBufferSize(camera_metadata_t *staticMeta,
806 uint32_t* outBufSize);
807 static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
808 static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
809 static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
810 std::unordered_set<std::string> *physicalIds/*out*/);
811 static Status getSupportedKeys(camera_metadata_t *staticMeta,
812 uint32_t tagId, std::unordered_set<int32_t> *requestIDs/*out*/);
813 static void fillOutputStreams(camera_metadata_ro_entry_t* entry,
814 std::vector<AvailableStream>& outputStreams,
815 const AvailableStream *threshold = nullptr,
816 const int32_t availableConfigOutputTag = 0u);
817 static void constructFilteredSettings(const sp<ICameraDeviceSession>& session,
818 const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
819 android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings/*out*/,
820 android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings
821 /*out*/);
822 static Status pickConstrainedModeSize(camera_metadata_t *staticMeta,
823 AvailableStream &hfrStream);
824 static Status isZSLModeAvailable(const camera_metadata_t *staticMeta);
825 static Status isZSLModeAvailable(const camera_metadata_t *staticMeta, ReprocessType reprocType);
826 static Status getZSLInputOutputMap(camera_metadata_t *staticMeta,
827 std::vector<AvailableZSLInputOutput> &inputOutputMap);
828 static Status findLargestSize(
829 const std::vector<AvailableStream> &streamSizes,
830 int32_t format, AvailableStream &result);
831 static Status isAutoFocusModeAvailable(
832 CameraParameters &cameraParams, const char *mode) ;
833 static Status isMonochromeCamera(const camera_metadata_t *staticMeta);
834
835 protected:
836
837 // In-flight queue for tracking completion of capture requests.
838 struct InFlightRequest {
839 // Set by notify() SHUTTER call.
840 nsecs_t shutterTimestamp;
841
842 bool errorCodeValid;
843 ErrorCode errorCode;
844
845 //Is partial result supported
846 bool usePartialResult;
847
848 //Partial result count expected
849 uint32_t numPartialResults;
850
851 // Message queue
852 std::shared_ptr<ResultMetadataQueue> resultQueue;
853
854 // Set by process_capture_result call with valid metadata
855 bool haveResultMetadata;
856
857 // Decremented by calls to process_capture_result with valid output
858 // and input buffers
859 ssize_t numBuffersLeft;
860
861 // A 64bit integer to index the frame number associated with this result.
862 int64_t frameNumber;
863
864 // The partial result count (index) for this capture result.
865 int32_t partialResultCount;
866
867 // For buffer drop errors, the stream ID for the stream that lost a buffer.
868 // Otherwise -1.
869 int32_t errorStreamId;
870
871 // If this request has any input buffer
872 bool hasInputBuffer;
873
874 // Result metadata
875 ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
876
877 // Buffers are added by process_capture_result when output buffers
878 // return from HAL but framework.
879 ::android::Vector<StreamBuffer> resultOutputBuffers;
880
InFlightRequestCameraHidlTest::InFlightRequest881 InFlightRequest() :
882 shutterTimestamp(0),
883 errorCodeValid(false),
884 errorCode(ErrorCode::ERROR_BUFFER),
885 usePartialResult(false),
886 numPartialResults(0),
887 resultQueue(nullptr),
888 haveResultMetadata(false),
889 numBuffersLeft(0),
890 frameNumber(0),
891 partialResultCount(0),
892 errorStreamId(-1),
893 hasInputBuffer(false) {}
894
InFlightRequestCameraHidlTest::InFlightRequest895 InFlightRequest(ssize_t numBuffers, bool hasInput,
896 bool partialResults, uint32_t partialCount,
897 std::shared_ptr<ResultMetadataQueue> queue = nullptr) :
898 shutterTimestamp(0),
899 errorCodeValid(false),
900 errorCode(ErrorCode::ERROR_BUFFER),
901 usePartialResult(partialResults),
902 numPartialResults(partialCount),
903 resultQueue(queue),
904 haveResultMetadata(false),
905 numBuffersLeft(numBuffers),
906 frameNumber(0),
907 partialResultCount(0),
908 errorStreamId(-1),
909 hasInputBuffer(hasInput) {}
910 };
911
912 // Map from frame number to the in-flight request state
913 typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap;
914
915 std::mutex mLock; // Synchronize access to member variables
916 std::condition_variable mResultCondition; // Condition variable for incoming results
917 InFlightMap mInflightMap; // Map of all inflight requests
918
919 DataCallbackMsg mDataMessageTypeReceived; // Most recent message type received through data callbacks
920 uint32_t mVideoBufferIndex; // Buffer index of the most recent video buffer
921 uint32_t mVideoData; // Buffer data of the most recent video buffer
922 hidl_handle mVideoNativeHandle; // Most recent video buffer native handle
923 NotifyCallbackMsg mNotifyMessage; // Current notification message
924
925 std::mutex mTorchLock; // Synchronize access to torch status
926 std::condition_variable mTorchCond; // Condition variable for torch status
927 TorchModeStatus mTorchStatus; // Current torch status
928
929 // Holds camera registered buffers
930 std::unordered_map<uint32_t, sp<::android::MemoryHeapBase> > mMemoryPool;
931
932 // Camera provider service
933 sp<ICameraProvider> mProvider;
934 sp<::android::hardware::camera::provider::V2_5::ICameraProvider> mProvider2_5;
935
936 // Camera provider type.
937 std::string mProviderType;
938 };
939
notifyCallback(NotifyCallbackMsg msgType,int32_t ext1 __unused,int32_t ext2 __unused)940 Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
941 NotifyCallbackMsg msgType, int32_t ext1 __unused,
942 int32_t ext2 __unused) {
943 std::unique_lock<std::mutex> l(mParent->mLock);
944 mParent->mNotifyMessage = msgType;
945 mParent->mResultCondition.notify_one();
946
947 return Void();
948 }
949
registerMemory(const hidl_handle & descriptor,uint32_t bufferSize,uint32_t bufferCount)950 Return<uint32_t> CameraHidlTest::Camera1DeviceCb::registerMemory(
951 const hidl_handle& descriptor, uint32_t bufferSize,
952 uint32_t bufferCount) {
953 if (descriptor->numFds != 1) {
954 ADD_FAILURE() << "camera memory descriptor has"
955 " numFds " << descriptor->numFds << " (expect 1)" ;
956 return 0;
957 }
958 if (descriptor->data[0] < 0) {
959 ADD_FAILURE() << "camera memory descriptor has"
960 " FD " << descriptor->data[0] << " (expect >= 0)";
961 return 0;
962 }
963
964 sp<::android::MemoryHeapBase> pool = new ::android::MemoryHeapBase(
965 descriptor->data[0], bufferSize*bufferCount, 0, 0);
966 mParent->mMemoryPool.emplace(pool->getHeapID(), pool);
967
968 return pool->getHeapID();
969 }
970
unregisterMemory(uint32_t memId)971 Return<void> CameraHidlTest::Camera1DeviceCb::unregisterMemory(uint32_t memId) {
972 if (mParent->mMemoryPool.count(memId) == 0) {
973 ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
974 ADD_FAILURE();
975 return Void();
976 }
977
978 mParent->mMemoryPool.erase(memId);
979 return Void();
980 }
981
dataCallback(DataCallbackMsg msgType __unused,uint32_t data __unused,uint32_t bufferIndex __unused,const CameraFrameMetadata & metadata __unused)982 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallback(
983 DataCallbackMsg msgType __unused, uint32_t data __unused,
984 uint32_t bufferIndex __unused,
985 const CameraFrameMetadata& metadata __unused) {
986 std::unique_lock<std::mutex> l(mParent->mLock);
987 mParent->mDataMessageTypeReceived = msgType;
988 mParent->mResultCondition.notify_one();
989
990 return Void();
991 }
992
dataCallbackTimestamp(DataCallbackMsg msgType,uint32_t data,uint32_t bufferIndex,int64_t timestamp __unused)993 Return<void> CameraHidlTest::Camera1DeviceCb::dataCallbackTimestamp(
994 DataCallbackMsg msgType, uint32_t data,
995 uint32_t bufferIndex, int64_t timestamp __unused) {
996 std::unique_lock<std::mutex> l(mParent->mLock);
997 mParent->mDataMessageTypeReceived = msgType;
998 mParent->mVideoBufferIndex = bufferIndex;
999 if (mParent->mMemoryPool.count(data) == 0) {
1000 ADD_FAILURE() << "memory pool ID " << data << "not found";
1001 }
1002 mParent->mVideoData = data;
1003 mParent->mResultCondition.notify_one();
1004
1005 return Void();
1006 }
1007
handleCallbackTimestamp(DataCallbackMsg msgType,const hidl_handle & frameData,uint32_t data __unused,uint32_t bufferIndex,int64_t timestamp __unused)1008 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestamp(
1009 DataCallbackMsg msgType, const hidl_handle& frameData,
1010 uint32_t data __unused, uint32_t bufferIndex,
1011 int64_t timestamp __unused) {
1012 std::unique_lock<std::mutex> l(mParent->mLock);
1013 mParent->mDataMessageTypeReceived = msgType;
1014 mParent->mVideoBufferIndex = bufferIndex;
1015 if (mParent->mMemoryPool.count(data) == 0) {
1016 ADD_FAILURE() << "memory pool ID " << data << " not found";
1017 }
1018 mParent->mVideoData = data;
1019 mParent->mVideoNativeHandle = frameData;
1020 mParent->mResultCondition.notify_one();
1021
1022 return Void();
1023 }
1024
handleCallbackTimestampBatch(DataCallbackMsg msgType,const hidl_vec<HandleTimestampMessage> & batch)1025 Return<void> CameraHidlTest::Camera1DeviceCb::handleCallbackTimestampBatch(
1026 DataCallbackMsg msgType,
1027 const hidl_vec<HandleTimestampMessage>& batch) {
1028 std::unique_lock<std::mutex> l(mParent->mLock);
1029 for (auto& msg : batch) {
1030 mParent->mDataMessageTypeReceived = msgType;
1031 mParent->mVideoBufferIndex = msg.bufferIndex;
1032 if (mParent->mMemoryPool.count(msg.data) == 0) {
1033 ADD_FAILURE() << "memory pool ID " << msg.data << " not found";
1034 }
1035 mParent->mVideoData = msg.data;
1036 mParent->mVideoNativeHandle = msg.frameData;
1037 mParent->mResultCondition.notify_one();
1038 }
1039 return Void();
1040 }
1041
processCaptureResult_3_4(const hidl_vec<V3_4::CaptureResult> & results)1042 Return<void> CameraHidlTest::DeviceCb::processCaptureResult_3_4(
1043 const hidl_vec<V3_4::CaptureResult>& results) {
1044
1045 if (nullptr == mParent) {
1046 return Void();
1047 }
1048
1049 bool notify = false;
1050 std::unique_lock<std::mutex> l(mParent->mLock);
1051 for (size_t i = 0 ; i < results.size(); i++) {
1052 notify = processCaptureResultLocked(results[i].v3_2, results[i].physicalCameraMetadata);
1053 }
1054
1055 l.unlock();
1056 if (notify) {
1057 mParent->mResultCondition.notify_one();
1058 }
1059
1060 return Void();
1061 }
1062
processCaptureResult(const hidl_vec<CaptureResult> & results)1063 Return<void> CameraHidlTest::DeviceCb::processCaptureResult(
1064 const hidl_vec<CaptureResult>& results) {
1065 if (nullptr == mParent) {
1066 return Void();
1067 }
1068
1069 bool notify = false;
1070 std::unique_lock<std::mutex> l(mParent->mLock);
1071 ::android::hardware::hidl_vec<PhysicalCameraMetadata> noPhysMetadata;
1072 for (size_t i = 0 ; i < results.size(); i++) {
1073 notify = processCaptureResultLocked(results[i], noPhysMetadata);
1074 }
1075
1076 l.unlock();
1077 if (notify) {
1078 mParent->mResultCondition.notify_one();
1079 }
1080
1081 return Void();
1082 }
1083
processCaptureResultLocked(const CaptureResult & results,hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata)1084 bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& results,
1085 hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata) {
1086 bool notify = false;
1087 uint32_t frameNumber = results.frameNumber;
1088
1089 if ((results.result.size() == 0) &&
1090 (results.outputBuffers.size() == 0) &&
1091 (results.inputBuffer.buffer == nullptr) &&
1092 (results.fmqResultSize == 0)) {
1093 ALOGE("%s: No result data provided by HAL for frame %d result count: %d",
1094 __func__, frameNumber, (int) results.fmqResultSize);
1095 ADD_FAILURE();
1096 return notify;
1097 }
1098
1099 ssize_t idx = mParent->mInflightMap.indexOfKey(frameNumber);
1100 if (::android::NAME_NOT_FOUND == idx) {
1101 ALOGE("%s: Unexpected frame number! received: %u",
1102 __func__, frameNumber);
1103 ADD_FAILURE();
1104 return notify;
1105 }
1106
1107 bool isPartialResult = false;
1108 bool hasInputBufferInRequest = false;
1109 InFlightRequest *request = mParent->mInflightMap.editValueAt(idx);
1110 ::android::hardware::camera::device::V3_2::CameraMetadata resultMetadata;
1111 size_t resultSize = 0;
1112 if (results.fmqResultSize > 0) {
1113 resultMetadata.resize(results.fmqResultSize);
1114 if (request->resultQueue == nullptr) {
1115 ADD_FAILURE();
1116 return notify;
1117 }
1118 if (!request->resultQueue->read(resultMetadata.data(),
1119 results.fmqResultSize)) {
1120 ALOGE("%s: Frame %d: Cannot read camera metadata from fmq,"
1121 "size = %" PRIu64, __func__, frameNumber,
1122 results.fmqResultSize);
1123 ADD_FAILURE();
1124 return notify;
1125 }
1126
1127 std::vector<::android::hardware::camera::device::V3_2::CameraMetadata> physResultMetadata;
1128 physResultMetadata.resize(physicalCameraMetadata.size());
1129 for (size_t i = 0; i < physicalCameraMetadata.size(); i++) {
1130 physResultMetadata[i].resize(physicalCameraMetadata[i].fmqMetadataSize);
1131 if (!request->resultQueue->read(physResultMetadata[i].data(),
1132 physicalCameraMetadata[i].fmqMetadataSize)) {
1133 ALOGE("%s: Frame %d: Cannot read physical camera metadata from fmq,"
1134 "size = %" PRIu64, __func__, frameNumber,
1135 physicalCameraMetadata[i].fmqMetadataSize);
1136 ADD_FAILURE();
1137 return notify;
1138 }
1139 }
1140 resultSize = resultMetadata.size();
1141 } else if (results.result.size() > 0) {
1142 resultMetadata.setToExternal(const_cast<uint8_t *>(
1143 results.result.data()), results.result.size());
1144 resultSize = resultMetadata.size();
1145 }
1146
1147 if (!request->usePartialResult && (resultSize > 0) &&
1148 (results.partialResult != 1)) {
1149 ALOGE("%s: Result is malformed for frame %d: partial_result %u "
1150 "must be 1 if partial result is not supported", __func__,
1151 frameNumber, results.partialResult);
1152 ADD_FAILURE();
1153 return notify;
1154 }
1155
1156 if (results.partialResult != 0) {
1157 request->partialResultCount = results.partialResult;
1158 }
1159
1160 // Check if this result carries only partial metadata
1161 if (request->usePartialResult && (resultSize > 0)) {
1162 if ((results.partialResult > request->numPartialResults) ||
1163 (results.partialResult < 1)) {
1164 ALOGE("%s: Result is malformed for frame %d: partial_result %u"
1165 " must be in the range of [1, %d] when metadata is "
1166 "included in the result", __func__, frameNumber,
1167 results.partialResult, request->numPartialResults);
1168 ADD_FAILURE();
1169 return notify;
1170 }
1171 request->collectedResult.append(
1172 reinterpret_cast<const camera_metadata_t*>(
1173 resultMetadata.data()));
1174
1175 isPartialResult =
1176 (results.partialResult < request->numPartialResults);
1177 } else if (resultSize > 0) {
1178 request->collectedResult.append(reinterpret_cast<const camera_metadata_t*>(
1179 resultMetadata.data()));
1180 isPartialResult = false;
1181 }
1182
1183 hasInputBufferInRequest = request->hasInputBuffer;
1184
1185 // Did we get the (final) result metadata for this capture?
1186 if ((resultSize > 0) && !isPartialResult) {
1187 if (request->haveResultMetadata) {
1188 ALOGE("%s: Called multiple times with metadata for frame %d",
1189 __func__, frameNumber);
1190 ADD_FAILURE();
1191 return notify;
1192 }
1193 request->haveResultMetadata = true;
1194 request->collectedResult.sort();
1195
1196 // Verify final result metadata
1197 bool isAtLeast_3_5 = mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_5;
1198 if (isAtLeast_3_5) {
1199 auto staticMetadataBuffer = mStaticMetadata.getAndLock();
1200 bool isMonochrome = Status::OK ==
1201 CameraHidlTest::isMonochromeCamera(staticMetadataBuffer);
1202 if (isMonochrome) {
1203 mParent->verifyMonochromeCameraResult(request->collectedResult);
1204 }
1205
1206 // Verify logical camera result metadata
1207 bool isLogicalCamera =
1208 Status::OK == CameraHidlTest::isLogicalMultiCamera(staticMetadataBuffer);
1209 if (isLogicalCamera) {
1210 mParent->verifyLogicalCameraResult(staticMetadataBuffer, request->collectedResult);
1211 }
1212 mStaticMetadata.unlock(staticMetadataBuffer);
1213 }
1214 }
1215
1216 uint32_t numBuffersReturned = results.outputBuffers.size();
1217 if (results.inputBuffer.buffer != nullptr) {
1218 if (hasInputBufferInRequest) {
1219 numBuffersReturned += 1;
1220 } else {
1221 ALOGW("%s: Input buffer should be NULL if there is no input"
1222 " buffer sent in the request", __func__);
1223 }
1224 }
1225 request->numBuffersLeft -= numBuffersReturned;
1226 if (request->numBuffersLeft < 0) {
1227 ALOGE("%s: Too many buffers returned for frame %d", __func__,
1228 frameNumber);
1229 ADD_FAILURE();
1230 return notify;
1231 }
1232
1233 request->resultOutputBuffers.appendArray(results.outputBuffers.data(),
1234 results.outputBuffers.size());
1235 // If shutter event is received notify the pending threads.
1236 if (request->shutterTimestamp != 0) {
1237 notify = true;
1238 }
1239
1240 if (mUseHalBufManager) {
1241 // Don't return buffers of bufId 0 (empty buffer)
1242 std::vector<StreamBuffer> buffers;
1243 for (const auto& sb : results.outputBuffers) {
1244 if (sb.bufferId != 0) {
1245 buffers.push_back(sb);
1246 }
1247 }
1248 returnStreamBuffers(buffers);
1249 }
1250 return notify;
1251 }
1252
setCurrentStreamConfig(const hidl_vec<V3_2::Stream> & streams,const hidl_vec<V3_2::HalStream> & halStreams)1253 void CameraHidlTest::DeviceCb::setCurrentStreamConfig(
1254 const hidl_vec<V3_2::Stream>& streams, const hidl_vec<V3_2::HalStream>& halStreams) {
1255 ASSERT_EQ(streams.size(), halStreams.size());
1256 ASSERT_NE(streams.size(), 0);
1257 for (size_t i = 0; i < streams.size(); i++) {
1258 ASSERT_EQ(streams[i].id, halStreams[i].id);
1259 }
1260 std::lock_guard<std::mutex> l(mLock);
1261 mUseHalBufManager = true;
1262 mStreams = streams;
1263 mHalStreams = halStreams;
1264 mOutstandingBufferIds.clear();
1265 for (size_t i = 0; i < streams.size(); i++) {
1266 mOutstandingBufferIds.emplace_back();
1267 }
1268 }
1269
hasOutstandingBuffersLocked()1270 bool CameraHidlTest::DeviceCb::hasOutstandingBuffersLocked() {
1271 if (!mUseHalBufManager) {
1272 return false;
1273 }
1274 for (const auto& outstandingBuffers : mOutstandingBufferIds) {
1275 if (!outstandingBuffers.empty()) {
1276 return true;
1277 }
1278 }
1279 return false;
1280 }
1281
waitForBuffersReturned()1282 void CameraHidlTest::DeviceCb::waitForBuffersReturned() {
1283 std::unique_lock<std::mutex> lk(mLock);
1284 if (hasOutstandingBuffersLocked()) {
1285 auto timeout = std::chrono::seconds(kBufferReturnTimeoutSec);
1286 auto st = mFlushedCondition.wait_for(lk, timeout);
1287 ASSERT_NE(std::cv_status::timeout, st);
1288 }
1289 }
1290
notify(const hidl_vec<NotifyMsg> & messages)1291 Return<void> CameraHidlTest::DeviceCb::notify(
1292 const hidl_vec<NotifyMsg>& messages) {
1293 std::lock_guard<std::mutex> l(mParent->mLock);
1294
1295 for (size_t i = 0; i < messages.size(); i++) {
1296 ssize_t idx = mParent->mInflightMap.indexOfKey(
1297 messages[i].msg.shutter.frameNumber);
1298 if (::android::NAME_NOT_FOUND == idx) {
1299 ALOGE("%s: Unexpected frame number! received: %u",
1300 __func__, messages[i].msg.shutter.frameNumber);
1301 ADD_FAILURE();
1302 break;
1303 }
1304 InFlightRequest *r = mParent->mInflightMap.editValueAt(idx);
1305
1306 switch(messages[i].type) {
1307 case MsgType::ERROR:
1308 if (ErrorCode::ERROR_DEVICE == messages[i].msg.error.errorCode) {
1309 ALOGE("%s: Camera reported serious device error",
1310 __func__);
1311 ADD_FAILURE();
1312 } else {
1313 r->errorCodeValid = true;
1314 r->errorCode = messages[i].msg.error.errorCode;
1315 r->errorStreamId = messages[i].msg.error.errorStreamId;
1316 }
1317 break;
1318 case MsgType::SHUTTER:
1319 r->shutterTimestamp = messages[i].msg.shutter.timestamp;
1320 break;
1321 default:
1322 ALOGE("%s: Unsupported notify message %d", __func__,
1323 messages[i].type);
1324 ADD_FAILURE();
1325 break;
1326 }
1327 }
1328
1329 mParent->mResultCondition.notify_one();
1330 return Void();
1331 }
1332
requestStreamBuffers(const hidl_vec<V3_5::BufferRequest> & bufReqs,requestStreamBuffers_cb _hidl_cb)1333 Return<void> CameraHidlTest::DeviceCb::requestStreamBuffers(
1334 const hidl_vec<V3_5::BufferRequest>& bufReqs,
1335 requestStreamBuffers_cb _hidl_cb) {
1336 using V3_5::BufferRequestStatus;
1337 using V3_5::StreamBufferRet;
1338 using V3_5::StreamBufferRequestError;
1339 hidl_vec<StreamBufferRet> bufRets;
1340 std::unique_lock<std::mutex> l(mLock);
1341
1342 if (!mUseHalBufManager) {
1343 ALOGE("%s: Camera does not support HAL buffer management", __FUNCTION__);
1344 ADD_FAILURE();
1345 _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
1346 return Void();
1347 }
1348
1349 if (bufReqs.size() > mStreams.size()) {
1350 ALOGE("%s: illegal buffer request: too many requests!", __FUNCTION__);
1351 ADD_FAILURE();
1352 _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
1353 return Void();
1354 }
1355
1356 std::vector<int32_t> indexes(bufReqs.size());
1357 for (size_t i = 0; i < bufReqs.size(); i++) {
1358 bool found = false;
1359 for (size_t idx = 0; idx < mStreams.size(); idx++) {
1360 if (bufReqs[i].streamId == mStreams[idx].id) {
1361 found = true;
1362 indexes[i] = idx;
1363 break;
1364 }
1365 }
1366 if (!found) {
1367 ALOGE("%s: illegal buffer request: unknown streamId %d!",
1368 __FUNCTION__, bufReqs[i].streamId);
1369 ADD_FAILURE();
1370 _hidl_cb(BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS, bufRets);
1371 return Void();
1372 }
1373 }
1374
1375 bool allStreamOk = true;
1376 bool atLeastOneStreamOk = false;
1377 bufRets.resize(bufReqs.size());
1378 for (size_t i = 0; i < bufReqs.size(); i++) {
1379 int32_t idx = indexes[i];
1380 const auto& stream = mStreams[idx];
1381 const auto& halStream = mHalStreams[idx];
1382 const V3_5::BufferRequest& bufReq = bufReqs[i];
1383 if (mOutstandingBufferIds[idx].size() + bufReq.numBuffersRequested > halStream.maxBuffers) {
1384 bufRets[i].streamId = stream.id;
1385 bufRets[i].val.error(StreamBufferRequestError::MAX_BUFFER_EXCEEDED);
1386 allStreamOk = false;
1387 continue;
1388 }
1389
1390 hidl_vec<StreamBuffer> tmpRetBuffers(bufReq.numBuffersRequested);
1391 for (size_t j = 0; j < bufReq.numBuffersRequested; j++) {
1392 hidl_handle buffer_handle;
1393 mParent->allocateGraphicBuffer(stream.width, stream.height,
1394 android_convertGralloc1To0Usage(
1395 halStream.producerUsage, halStream.consumerUsage),
1396 halStream.overrideFormat, &buffer_handle);
1397
1398 tmpRetBuffers[j] = {stream.id, mNextBufferId, buffer_handle, BufferStatus::OK,
1399 nullptr, nullptr};
1400 mOutstandingBufferIds[idx].insert(std::make_pair(mNextBufferId++, buffer_handle));
1401 }
1402 atLeastOneStreamOk = true;
1403 bufRets[i].streamId = stream.id;
1404 bufRets[i].val.buffers(std::move(tmpRetBuffers));
1405 }
1406
1407 if (allStreamOk) {
1408 _hidl_cb(BufferRequestStatus::OK, bufRets);
1409 } else if (atLeastOneStreamOk) {
1410 _hidl_cb(BufferRequestStatus::FAILED_PARTIAL, bufRets);
1411 } else {
1412 _hidl_cb(BufferRequestStatus::FAILED_UNKNOWN, bufRets);
1413 }
1414
1415 if (!hasOutstandingBuffersLocked()) {
1416 l.unlock();
1417 mFlushedCondition.notify_one();
1418 }
1419 return Void();
1420 }
1421
returnStreamBuffers(const hidl_vec<StreamBuffer> & buffers)1422 Return<void> CameraHidlTest::DeviceCb::returnStreamBuffers(
1423 const hidl_vec<StreamBuffer>& buffers) {
1424 if (!mUseHalBufManager) {
1425 ALOGE("%s: Camera does not support HAL buffer management", __FUNCTION__);
1426 ADD_FAILURE();
1427 }
1428
1429 std::lock_guard<std::mutex> l(mLock);
1430 for (const auto& buf : buffers) {
1431 bool found = false;
1432 for (size_t idx = 0; idx < mOutstandingBufferIds.size(); idx++) {
1433 if (mStreams[idx].id == buf.streamId &&
1434 mOutstandingBufferIds[idx].count(buf.bufferId) == 1) {
1435 mOutstandingBufferIds[idx].erase(buf.bufferId);
1436 // TODO: check do we need to close/delete native handle or assume we have enough
1437 // memory to run till the test finish? since we do not capture much requests (and
1438 // most of time one buffer is sufficient)
1439 found = true;
1440 break;
1441 }
1442 }
1443 if (found) {
1444 continue;
1445 }
1446 ALOGE("%s: unknown buffer ID %" PRIu64, __FUNCTION__, buf.bufferId);
1447 ADD_FAILURE();
1448 }
1449 return Void();
1450 }
1451
getCameraDeviceNames(sp<ICameraProvider> provider)1452 hidl_vec<hidl_string> CameraHidlTest::getCameraDeviceNames(sp<ICameraProvider> provider) {
1453 std::vector<std::string> cameraDeviceNames;
1454 Return<void> ret;
1455 ret = provider->getCameraIdList(
1456 [&](auto status, const auto& idList) {
1457 ALOGI("getCameraIdList returns status:%d", (int)status);
1458 for (size_t i = 0; i < idList.size(); i++) {
1459 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
1460 }
1461 ASSERT_EQ(Status::OK, status);
1462 for (const auto& id : idList) {
1463 cameraDeviceNames.push_back(id);
1464 }
1465 });
1466 if (!ret.isOk()) {
1467 ADD_FAILURE();
1468 }
1469
1470 // External camera devices are reported through cameraDeviceStatusChange
1471 struct ProviderCb : public ICameraProviderCallback {
1472 virtual Return<void> cameraDeviceStatusChange(
1473 const hidl_string& devName,
1474 CameraDeviceStatus newStatus) override {
1475 ALOGI("camera device status callback name %s, status %d",
1476 devName.c_str(), (int) newStatus);
1477 if (newStatus == CameraDeviceStatus::PRESENT) {
1478 externalCameraDeviceNames.push_back(devName);
1479
1480 }
1481 return Void();
1482 }
1483
1484 virtual Return<void> torchModeStatusChange(
1485 const hidl_string&, TorchModeStatus) override {
1486 return Void();
1487 }
1488
1489 std::vector<std::string> externalCameraDeviceNames;
1490 };
1491 sp<ProviderCb> cb = new ProviderCb;
1492 auto status = mProvider->setCallback(cb);
1493
1494 for (const auto& devName : cb->externalCameraDeviceNames) {
1495 if (cameraDeviceNames.end() == std::find(
1496 cameraDeviceNames.begin(), cameraDeviceNames.end(), devName)) {
1497 cameraDeviceNames.push_back(devName);
1498 }
1499 }
1500
1501 hidl_vec<hidl_string> retList(cameraDeviceNames.size());
1502 for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
1503 retList[i] = cameraDeviceNames[i];
1504 }
1505 return retList;
1506 }
1507
1508 // Test devices with first_api_level >= P does not advertise device@1.0
TEST_F(CameraHidlTest,noHal1AfterP)1509 TEST_F(CameraHidlTest, noHal1AfterP) {
1510 constexpr int32_t HAL1_PHASE_OUT_API_LEVEL = 28;
1511 int32_t firstApiLevel = 0;
1512 getFirstApiLevel(&firstApiLevel);
1513
1514 // all devices with first API level == 28 and <= 1GB of RAM must set low_ram
1515 // and thus be allowed to continue using HAL1
1516 if ((firstApiLevel == HAL1_PHASE_OUT_API_LEVEL) &&
1517 (property_get_bool("ro.config.low_ram", /*default*/ false))) {
1518 ALOGI("Hal1 allowed for low ram device");
1519 return;
1520 }
1521
1522 if (firstApiLevel >= HAL1_PHASE_OUT_API_LEVEL) {
1523 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1524 for (const auto& name : cameraDeviceNames) {
1525 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1526 ASSERT_NE(deviceVersion, 0); // Must be a valid device version
1527 ASSERT_NE(deviceVersion, CAMERA_DEVICE_API_VERSION_1_0); // Must not be device@1.0
1528 }
1529 }
1530 }
1531
1532 // Test if ICameraProvider::isTorchModeSupported returns Status::OK
1533 // Also if first_api_level >= Q torch API must be supported.
TEST_F(CameraHidlTest,isTorchModeSupported)1534 TEST_F(CameraHidlTest, isTorchModeSupported) {
1535 constexpr int32_t API_LEVEL_Q = 29;
1536 int32_t firstApiLevel = 0;
1537 getFirstApiLevel(&firstApiLevel);
1538
1539 Return<void> ret;
1540 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
1541 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
1542 ASSERT_EQ(Status::OK, status);
1543 if (firstApiLevel >= API_LEVEL_Q) {
1544 ASSERT_EQ(true, support);
1545 }
1546 });
1547 ASSERT_TRUE(ret.isOk());
1548 }
1549
1550 // TODO: consider removing this test if getCameraDeviceNames() has the same coverage
TEST_F(CameraHidlTest,getCameraIdList)1551 TEST_F(CameraHidlTest, getCameraIdList) {
1552 Return<void> ret;
1553 ret = mProvider->getCameraIdList([&](auto status, const auto& idList) {
1554 ALOGI("getCameraIdList returns status:%d", (int)status);
1555 for (size_t i = 0; i < idList.size(); i++) {
1556 ALOGI("Camera Id[%zu] is %s", i, idList[i].c_str());
1557 }
1558 ASSERT_EQ(Status::OK, status);
1559 });
1560 ASSERT_TRUE(ret.isOk());
1561 }
1562
1563 // Test if ICameraProvider::getVendorTags returns Status::OK
TEST_F(CameraHidlTest,getVendorTags)1564 TEST_F(CameraHidlTest, getVendorTags) {
1565 Return<void> ret;
1566 ret = mProvider->getVendorTags([&](auto status, const auto& vendorTagSecs) {
1567 ALOGI("getVendorTags returns status:%d numSections %zu", (int)status, vendorTagSecs.size());
1568 for (size_t i = 0; i < vendorTagSecs.size(); i++) {
1569 ALOGI("Vendor tag section %zu name %s", i, vendorTagSecs[i].sectionName.c_str());
1570 for (size_t j = 0; j < vendorTagSecs[i].tags.size(); j++) {
1571 const auto& tag = vendorTagSecs[i].tags[j];
1572 ALOGI("Vendor tag id %u name %s type %d", tag.tagId, tag.tagName.c_str(),
1573 (int)tag.tagType);
1574 }
1575 }
1576 ASSERT_EQ(Status::OK, status);
1577 });
1578 ASSERT_TRUE(ret.isOk());
1579 }
1580
1581 // Test if ICameraProvider::setCallback returns Status::OK
TEST_F(CameraHidlTest,setCallback)1582 TEST_F(CameraHidlTest, setCallback) {
1583 struct ProviderCb : public ICameraProviderCallback {
1584 virtual Return<void> cameraDeviceStatusChange(
1585 const hidl_string& cameraDeviceName,
1586 CameraDeviceStatus newStatus) override {
1587 ALOGI("camera device status callback name %s, status %d",
1588 cameraDeviceName.c_str(), (int) newStatus);
1589 return Void();
1590 }
1591
1592 virtual Return<void> torchModeStatusChange(
1593 const hidl_string& cameraDeviceName,
1594 TorchModeStatus newStatus) override {
1595 ALOGI("Torch mode status callback name %s, status %d",
1596 cameraDeviceName.c_str(), (int) newStatus);
1597 return Void();
1598 }
1599 };
1600 sp<ProviderCb> cb = new ProviderCb;
1601 auto status = mProvider->setCallback(cb);
1602 ASSERT_TRUE(status.isOk());
1603 ASSERT_EQ(Status::OK, status);
1604 status = mProvider->setCallback(nullptr);
1605 ASSERT_TRUE(status.isOk());
1606 ASSERT_EQ(Status::OK, status);
1607 }
1608
1609 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
TEST_F(CameraHidlTest,getCameraDeviceInterface)1610 TEST_F(CameraHidlTest, getCameraDeviceInterface) {
1611 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1612
1613 for (const auto& name : cameraDeviceNames) {
1614 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1615 switch (deviceVersion) {
1616 case CAMERA_DEVICE_API_VERSION_3_5:
1617 case CAMERA_DEVICE_API_VERSION_3_4:
1618 case CAMERA_DEVICE_API_VERSION_3_3:
1619 case CAMERA_DEVICE_API_VERSION_3_2: {
1620 Return<void> ret;
1621 ret = mProvider->getCameraDeviceInterface_V3_x(
1622 name, [&](auto status, const auto& device3_x) {
1623 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1624 ASSERT_EQ(Status::OK, status);
1625 ASSERT_NE(device3_x, nullptr);
1626 });
1627 ASSERT_TRUE(ret.isOk());
1628 }
1629 break;
1630 case CAMERA_DEVICE_API_VERSION_1_0: {
1631 Return<void> ret;
1632 ret = mProvider->getCameraDeviceInterface_V1_x(
1633 name, [&](auto status, const auto& device1) {
1634 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1635 ASSERT_EQ(Status::OK, status);
1636 ASSERT_NE(device1, nullptr);
1637 });
1638 ASSERT_TRUE(ret.isOk());
1639 }
1640 break;
1641 default: {
1642 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1643 ADD_FAILURE();
1644 }
1645 break;
1646 }
1647 }
1648 }
1649
1650 // Verify that the device resource cost can be retrieved and the values are
1651 // sane.
TEST_F(CameraHidlTest,getResourceCost)1652 TEST_F(CameraHidlTest, getResourceCost) {
1653 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1654
1655 for (const auto& name : cameraDeviceNames) {
1656 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
1657 switch (deviceVersion) {
1658 case CAMERA_DEVICE_API_VERSION_3_5:
1659 case CAMERA_DEVICE_API_VERSION_3_4:
1660 case CAMERA_DEVICE_API_VERSION_3_3:
1661 case CAMERA_DEVICE_API_VERSION_3_2: {
1662 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
1663 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
1664 Return<void> ret;
1665 ret = mProvider->getCameraDeviceInterface_V3_x(
1666 name, [&](auto status, const auto& device) {
1667 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
1668 ASSERT_EQ(Status::OK, status);
1669 ASSERT_NE(device, nullptr);
1670 device3_x = device;
1671 });
1672 ASSERT_TRUE(ret.isOk());
1673
1674 ret = device3_x->getResourceCost([&](auto status, const auto& resourceCost) {
1675 ALOGI("getResourceCost returns status:%d", (int)status);
1676 ASSERT_EQ(Status::OK, status);
1677 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
1678 ASSERT_LE(resourceCost.resourceCost, 100u);
1679 for (const auto& name : resourceCost.conflictingDevices) {
1680 ALOGI(" Conflicting device: %s", name.c_str());
1681 }
1682 });
1683 ASSERT_TRUE(ret.isOk());
1684 }
1685 break;
1686 case CAMERA_DEVICE_API_VERSION_1_0: {
1687 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1688 ALOGI("getResourceCost: Testing camera device %s", name.c_str());
1689 Return<void> ret;
1690 ret = mProvider->getCameraDeviceInterface_V1_x(
1691 name, [&](auto status, const auto& device) {
1692 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1693 ASSERT_EQ(Status::OK, status);
1694 ASSERT_NE(device, nullptr);
1695 device1 = device;
1696 });
1697 ASSERT_TRUE(ret.isOk());
1698
1699 ret = device1->getResourceCost([&](auto status, const auto& resourceCost) {
1700 ALOGI("getResourceCost returns status:%d", (int)status);
1701 ASSERT_EQ(Status::OK, status);
1702 ALOGI(" Resource cost is %d", resourceCost.resourceCost);
1703 ASSERT_LE(resourceCost.resourceCost, 100u);
1704 for (const auto& name : resourceCost.conflictingDevices) {
1705 ALOGI(" Conflicting device: %s", name.c_str());
1706 }
1707 });
1708 ASSERT_TRUE(ret.isOk());
1709 }
1710 break;
1711 default: {
1712 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
1713 ADD_FAILURE();
1714 }
1715 break;
1716 }
1717 }
1718 }
1719
1720 // Verify that the static camera info can be retrieved
1721 // successfully.
TEST_F(CameraHidlTest,getCameraInfo)1722 TEST_F(CameraHidlTest, getCameraInfo) {
1723 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1724
1725 for (const auto& name : cameraDeviceNames) {
1726 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1727 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1728 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1729 Return<void> ret;
1730 ret = mProvider->getCameraDeviceInterface_V1_x(
1731 name, [&](auto status, const auto& device) {
1732 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1733 ASSERT_EQ(Status::OK, status);
1734 ASSERT_NE(device, nullptr);
1735 device1 = device;
1736 });
1737 ASSERT_TRUE(ret.isOk());
1738
1739 ret = device1->getCameraInfo([&](auto status, const auto& info) {
1740 ALOGI("getCameraInfo returns status:%d", (int)status);
1741 ASSERT_EQ(Status::OK, status);
1742 switch (info.orientation) {
1743 case 0:
1744 case 90:
1745 case 180:
1746 case 270:
1747 // Expected cases
1748 ALOGI("camera orientation: %d", info.orientation);
1749 break;
1750 default:
1751 FAIL() << "Unexpected camera orientation:" << info.orientation;
1752 }
1753 switch (info.facing) {
1754 case CameraFacing::BACK:
1755 case CameraFacing::FRONT:
1756 case CameraFacing::EXTERNAL:
1757 // Expected cases
1758 ALOGI("camera facing: %d", info.facing);
1759 break;
1760 default:
1761 FAIL() << "Unexpected camera facing:" << static_cast<uint32_t>(info.facing);
1762 }
1763 });
1764 ASSERT_TRUE(ret.isOk());
1765 }
1766 }
1767 }
1768
1769 // Check whether preview window can be configured
TEST_F(CameraHidlTest,setPreviewWindow)1770 TEST_F(CameraHidlTest, setPreviewWindow) {
1771 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1772
1773 for (const auto& name : cameraDeviceNames) {
1774 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1775 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1776 openCameraDevice(name, mProvider, &device1 /*out*/);
1777 ASSERT_NE(nullptr, device1.get());
1778 sp<BufferItemConsumer> bufferItemConsumer;
1779 sp<BufferItemHander> bufferHandler;
1780 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1781
1782 Return<void> ret;
1783 ret = device1->close();
1784 ASSERT_TRUE(ret.isOk());
1785 }
1786 }
1787 }
1788
1789 // Verify that setting preview window fails in case device is not open
TEST_F(CameraHidlTest,setPreviewWindowInvalid)1790 TEST_F(CameraHidlTest, setPreviewWindowInvalid) {
1791 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1792
1793 for (const auto& name : cameraDeviceNames) {
1794 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1795 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1796 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
1797 Return<void> ret;
1798 ret = mProvider->getCameraDeviceInterface_V1_x(
1799 name, [&](auto status, const auto& device) {
1800 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
1801 ASSERT_EQ(Status::OK, status);
1802 ASSERT_NE(device, nullptr);
1803 device1 = device;
1804 });
1805 ASSERT_TRUE(ret.isOk());
1806
1807 Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1808 ASSERT_TRUE(returnStatus.isOk());
1809 ASSERT_EQ(Status::OPERATION_NOT_SUPPORTED, returnStatus);
1810 }
1811 }
1812 }
1813
1814 // Start and stop preview checking whether it gets enabled in between.
TEST_F(CameraHidlTest,startStopPreview)1815 TEST_F(CameraHidlTest, startStopPreview) {
1816 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1817
1818 for (const auto& name : cameraDeviceNames) {
1819 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1820 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1821 openCameraDevice(name, mProvider, &device1 /*out*/);
1822 ASSERT_NE(nullptr, device1.get());
1823 sp<BufferItemConsumer> bufferItemConsumer;
1824 sp<BufferItemHander> bufferHandler;
1825 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1826
1827 startPreview(device1);
1828
1829 Return<bool> returnBoolStatus = device1->previewEnabled();
1830 ASSERT_TRUE(returnBoolStatus.isOk());
1831 ASSERT_TRUE(returnBoolStatus);
1832
1833 stopPreviewAndClose(device1);
1834 }
1835 }
1836 }
1837
1838 // Start preview without active preview window. Preview should start as soon
1839 // as a valid active window gets configured.
TEST_F(CameraHidlTest,startStopPreviewDelayed)1840 TEST_F(CameraHidlTest, startStopPreviewDelayed) {
1841 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1842
1843 for (const auto& name : cameraDeviceNames) {
1844 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1845 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1846 openCameraDevice(name, mProvider, &device1 /*out*/);
1847 ASSERT_NE(nullptr, device1.get());
1848
1849 Return<Status> returnStatus = device1->setPreviewWindow(nullptr);
1850 ASSERT_TRUE(returnStatus.isOk());
1851 ASSERT_EQ(Status::OK, returnStatus);
1852
1853 startPreview(device1);
1854
1855 sp<BufferItemConsumer> bufferItemConsumer;
1856 sp<BufferItemHander> bufferHandler;
1857 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1858
1859 // Preview should get enabled now
1860 Return<bool> returnBoolStatus = device1->previewEnabled();
1861 ASSERT_TRUE(returnBoolStatus.isOk());
1862 ASSERT_TRUE(returnBoolStatus);
1863
1864 stopPreviewAndClose(device1);
1865 }
1866 }
1867 }
1868
1869 // Verify that image capture behaves as expected along with preview callbacks.
TEST_F(CameraHidlTest,takePicture)1870 TEST_F(CameraHidlTest, takePicture) {
1871 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1872
1873 for (const auto& name : cameraDeviceNames) {
1874 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1875 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1876 openCameraDevice(name, mProvider, &device1 /*out*/);
1877 ASSERT_NE(nullptr, device1.get());
1878 sp<BufferItemConsumer> bufferItemConsumer;
1879 sp<BufferItemHander> bufferHandler;
1880 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1881
1882 {
1883 std::unique_lock<std::mutex> l(mLock);
1884 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1885 }
1886
1887 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1888 startPreview(device1);
1889
1890 {
1891 std::unique_lock<std::mutex> l(mLock);
1892 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
1893 }
1894
1895 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
1896 enableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1);
1897
1898 {
1899 std::unique_lock<std::mutex> l(mLock);
1900 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
1901 }
1902
1903 Return<Status> returnStatus = device1->takePicture();
1904 ASSERT_TRUE(returnStatus.isOk());
1905 ASSERT_EQ(Status::OK, returnStatus);
1906
1907 {
1908 std::unique_lock<std::mutex> l(mLock);
1909 waitForFrameLocked(DataCallbackMsg::COMPRESSED_IMAGE, l);
1910 }
1911
1912 disableMsgType((unsigned int)DataCallbackMsg::COMPRESSED_IMAGE, device1);
1913 stopPreviewAndClose(device1);
1914 }
1915 }
1916 }
1917
1918 // Image capture should fail in case preview didn't get enabled first.
TEST_F(CameraHidlTest,takePictureFail)1919 TEST_F(CameraHidlTest, takePictureFail) {
1920 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1921
1922 for (const auto& name : cameraDeviceNames) {
1923 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1924 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1925 openCameraDevice(name, mProvider, &device1 /*out*/);
1926 ASSERT_NE(nullptr, device1.get());
1927
1928 Return<Status> returnStatus = device1->takePicture();
1929 ASSERT_TRUE(returnStatus.isOk());
1930 ASSERT_NE(Status::OK, returnStatus);
1931
1932 Return<void> ret = device1->close();
1933 ASSERT_TRUE(ret.isOk());
1934 }
1935 }
1936 }
1937
1938 // Verify that image capture can be cancelled.
TEST_F(CameraHidlTest,cancelPicture)1939 TEST_F(CameraHidlTest, cancelPicture) {
1940 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1941
1942 for (const auto& name : cameraDeviceNames) {
1943 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1944 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1945 openCameraDevice(name, mProvider, &device1 /*out*/);
1946 ASSERT_NE(nullptr, device1.get());
1947 sp<BufferItemConsumer> bufferItemConsumer;
1948 sp<BufferItemHander> bufferHandler;
1949 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1950 startPreview(device1);
1951
1952 Return<Status> returnStatus = device1->takePicture();
1953 ASSERT_TRUE(returnStatus.isOk());
1954 ASSERT_EQ(Status::OK, returnStatus);
1955
1956 returnStatus = device1->cancelPicture();
1957 ASSERT_TRUE(returnStatus.isOk());
1958 ASSERT_EQ(Status::OK, returnStatus);
1959
1960 stopPreviewAndClose(device1);
1961 }
1962 }
1963 }
1964
1965 // Image capture cancel is a no-op when image capture is not running.
TEST_F(CameraHidlTest,cancelPictureNOP)1966 TEST_F(CameraHidlTest, cancelPictureNOP) {
1967 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1968
1969 for (const auto& name : cameraDeviceNames) {
1970 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1971 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1972 openCameraDevice(name, mProvider, &device1 /*out*/);
1973 ASSERT_NE(nullptr, device1.get());
1974 sp<BufferItemConsumer> bufferItemConsumer;
1975 sp<BufferItemHander> bufferHandler;
1976 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
1977 startPreview(device1);
1978
1979 Return<Status> returnStatus = device1->cancelPicture();
1980 ASSERT_TRUE(returnStatus.isOk());
1981 ASSERT_EQ(Status::OK, returnStatus);
1982
1983 stopPreviewAndClose(device1);
1984 }
1985 }
1986 }
1987
1988 // Test basic video recording.
TEST_F(CameraHidlTest,startStopRecording)1989 TEST_F(CameraHidlTest, startStopRecording) {
1990 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
1991
1992 for (const auto& name : cameraDeviceNames) {
1993 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
1994 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
1995 openCameraDevice(name, mProvider, &device1 /*out*/);
1996 ASSERT_NE(nullptr, device1.get());
1997 sp<BufferItemConsumer> bufferItemConsumer;
1998 sp<BufferItemHander> bufferHandler;
1999 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2000
2001 {
2002 std::unique_lock<std::mutex> l(mLock);
2003 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
2004 }
2005
2006 enableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
2007 startPreview(device1);
2008
2009 {
2010 std::unique_lock<std::mutex> l(mLock);
2011 waitForFrameLocked(DataCallbackMsg::PREVIEW_FRAME, l);
2012 mDataMessageTypeReceived = DataCallbackMsg::RAW_IMAGE_NOTIFY;
2013 mVideoBufferIndex = UINT32_MAX;
2014 }
2015
2016 disableMsgType((unsigned int)DataCallbackMsg::PREVIEW_FRAME, device1);
2017
2018 bool videoMetaEnabled = false;
2019 Return<Status> returnStatus = device1->storeMetaDataInBuffers(true);
2020 ASSERT_TRUE(returnStatus.isOk());
2021 // It is allowed for devices to not support this feature
2022 ASSERT_TRUE((Status::OK == returnStatus) ||
2023 (Status::OPERATION_NOT_SUPPORTED == returnStatus));
2024 if (Status::OK == returnStatus) {
2025 videoMetaEnabled = true;
2026 }
2027
2028 enableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
2029 Return<bool> returnBoolStatus = device1->recordingEnabled();
2030 ASSERT_TRUE(returnBoolStatus.isOk());
2031 ASSERT_FALSE(returnBoolStatus);
2032
2033 returnStatus = device1->startRecording();
2034 ASSERT_TRUE(returnStatus.isOk());
2035 ASSERT_EQ(Status::OK, returnStatus);
2036
2037 {
2038 std::unique_lock<std::mutex> l(mLock);
2039 waitForFrameLocked(DataCallbackMsg::VIDEO_FRAME, l);
2040 ASSERT_NE(UINT32_MAX, mVideoBufferIndex);
2041 disableMsgType((unsigned int)DataCallbackMsg::VIDEO_FRAME, device1);
2042 }
2043
2044 returnBoolStatus = device1->recordingEnabled();
2045 ASSERT_TRUE(returnBoolStatus.isOk());
2046 ASSERT_TRUE(returnBoolStatus);
2047
2048 Return<void> ret;
2049 if (videoMetaEnabled) {
2050 ret = device1->releaseRecordingFrameHandle(mVideoData, mVideoBufferIndex,
2051 mVideoNativeHandle);
2052 ASSERT_TRUE(ret.isOk());
2053 } else {
2054 ret = device1->releaseRecordingFrame(mVideoData, mVideoBufferIndex);
2055 ASSERT_TRUE(ret.isOk());
2056 }
2057
2058 ret = device1->stopRecording();
2059 ASSERT_TRUE(ret.isOk());
2060
2061 stopPreviewAndClose(device1);
2062 }
2063 }
2064 }
2065
2066 // It shouldn't be possible to start recording without enabling preview first.
TEST_F(CameraHidlTest,startRecordingFail)2067 TEST_F(CameraHidlTest, startRecordingFail) {
2068 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2069
2070 for (const auto& name : cameraDeviceNames) {
2071 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2072 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2073 openCameraDevice(name, mProvider, &device1 /*out*/);
2074 ASSERT_NE(nullptr, device1.get());
2075
2076 Return<bool> returnBoolStatus = device1->recordingEnabled();
2077 ASSERT_TRUE(returnBoolStatus.isOk());
2078 ASSERT_FALSE(returnBoolStatus);
2079
2080 Return<Status> returnStatus = device1->startRecording();
2081 ASSERT_TRUE(returnStatus.isOk());
2082 ASSERT_NE(Status::OK, returnStatus);
2083
2084 Return<void> ret = device1->close();
2085 ASSERT_TRUE(ret.isOk());
2086 }
2087 }
2088 }
2089
2090 // Check autofocus support if available.
TEST_F(CameraHidlTest,autoFocus)2091 TEST_F(CameraHidlTest, autoFocus) {
2092 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2093 std::vector<const char*> focusModes = {CameraParameters::FOCUS_MODE_AUTO,
2094 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE,
2095 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO};
2096
2097 for (const auto& name : cameraDeviceNames) {
2098 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2099 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2100 openCameraDevice(name, mProvider, &device1 /*out*/);
2101 ASSERT_NE(nullptr, device1.get());
2102
2103 CameraParameters cameraParams;
2104 getParameters(device1, &cameraParams /*out*/);
2105
2106 if (Status::OK !=
2107 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
2108 Return<void> ret = device1->close();
2109 ASSERT_TRUE(ret.isOk());
2110 continue;
2111 }
2112
2113 sp<BufferItemConsumer> bufferItemConsumer;
2114 sp<BufferItemHander> bufferHandler;
2115 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2116 startPreview(device1);
2117 enableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
2118
2119 for (auto& iter : focusModes) {
2120 if (Status::OK != isAutoFocusModeAvailable(cameraParams, iter)) {
2121 continue;
2122 }
2123
2124 cameraParams.set(CameraParameters::KEY_FOCUS_MODE, iter);
2125 setParameters(device1, cameraParams);
2126 {
2127 std::unique_lock<std::mutex> l(mLock);
2128 mNotifyMessage = NotifyCallbackMsg::ERROR;
2129 }
2130
2131 Return<Status> returnStatus = device1->autoFocus();
2132 ASSERT_TRUE(returnStatus.isOk());
2133 ASSERT_EQ(Status::OK, returnStatus);
2134
2135 {
2136 std::unique_lock<std::mutex> l(mLock);
2137 while (NotifyCallbackMsg::FOCUS != mNotifyMessage) {
2138 auto timeout = std::chrono::system_clock::now() +
2139 std::chrono::seconds(kAutoFocusTimeoutSec);
2140 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
2141 }
2142 }
2143 }
2144
2145 disableMsgType((unsigned int)NotifyCallbackMsg::FOCUS, device1);
2146 stopPreviewAndClose(device1);
2147 }
2148 }
2149 }
2150
2151 // In case autofocus is supported verify that it can be cancelled.
TEST_F(CameraHidlTest,cancelAutoFocus)2152 TEST_F(CameraHidlTest, cancelAutoFocus) {
2153 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2154
2155 for (const auto& name : cameraDeviceNames) {
2156 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2157 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2158 openCameraDevice(name, mProvider, &device1 /*out*/);
2159 ASSERT_NE(nullptr, device1.get());
2160
2161 CameraParameters cameraParams;
2162 getParameters(device1, &cameraParams /*out*/);
2163
2164 if (Status::OK !=
2165 isAutoFocusModeAvailable(cameraParams, CameraParameters::FOCUS_MODE_AUTO)) {
2166 Return<void> ret = device1->close();
2167 ASSERT_TRUE(ret.isOk());
2168 continue;
2169 }
2170
2171 // It should be fine to call before preview starts.
2172 ASSERT_EQ(Status::OK, device1->cancelAutoFocus());
2173
2174 sp<BufferItemConsumer> bufferItemConsumer;
2175 sp<BufferItemHander> bufferHandler;
2176 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2177 startPreview(device1);
2178
2179 // It should be fine to call after preview starts too.
2180 Return<Status> returnStatus = device1->cancelAutoFocus();
2181 ASSERT_TRUE(returnStatus.isOk());
2182 ASSERT_EQ(Status::OK, returnStatus);
2183
2184 returnStatus = device1->autoFocus();
2185 ASSERT_TRUE(returnStatus.isOk());
2186 ASSERT_EQ(Status::OK, returnStatus);
2187
2188 returnStatus = device1->cancelAutoFocus();
2189 ASSERT_TRUE(returnStatus.isOk());
2190 ASSERT_EQ(Status::OK, returnStatus);
2191
2192 stopPreviewAndClose(device1);
2193 }
2194 }
2195 }
2196
2197 // Check whether face detection is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandFaceDetection)2198 TEST_F(CameraHidlTest, sendCommandFaceDetection) {
2199 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2200
2201 for (const auto& name : cameraDeviceNames) {
2202 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2203 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2204 openCameraDevice(name, mProvider, &device1 /*out*/);
2205 ASSERT_NE(nullptr, device1.get());
2206
2207 CameraParameters cameraParams;
2208 getParameters(device1, &cameraParams /*out*/);
2209
2210 int32_t hwFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW);
2211 int32_t swFaces = cameraParams.getInt(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW);
2212 if ((0 >= hwFaces) && (0 >= swFaces)) {
2213 Return<void> ret = device1->close();
2214 ASSERT_TRUE(ret.isOk());
2215 continue;
2216 }
2217
2218 sp<BufferItemConsumer> bufferItemConsumer;
2219 sp<BufferItemHander> bufferHandler;
2220 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2221 startPreview(device1);
2222
2223 if (0 < hwFaces) {
2224 Return<Status> returnStatus = device1->sendCommand(
2225 CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_HW, 0);
2226 ASSERT_TRUE(returnStatus.isOk());
2227 ASSERT_EQ(Status::OK, returnStatus);
2228 // TODO(epeev) : Enable and check for face notifications
2229 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION,
2230 CAMERA_FACE_DETECTION_HW, 0);
2231 ASSERT_TRUE(returnStatus.isOk());
2232 ASSERT_EQ(Status::OK, returnStatus);
2233 }
2234
2235 if (0 < swFaces) {
2236 Return<Status> returnStatus = device1->sendCommand(
2237 CommandType::START_FACE_DETECTION, CAMERA_FACE_DETECTION_SW, 0);
2238 ASSERT_TRUE(returnStatus.isOk());
2239 ASSERT_EQ(Status::OK, returnStatus);
2240 // TODO(epeev) : Enable and check for face notifications
2241 returnStatus = device1->sendCommand(CommandType::STOP_FACE_DETECTION,
2242 CAMERA_FACE_DETECTION_SW, 0);
2243 ASSERT_TRUE(returnStatus.isOk());
2244 ASSERT_EQ(Status::OK, returnStatus);
2245 }
2246
2247 stopPreviewAndClose(device1);
2248 }
2249 }
2250 }
2251
2252 // Check whether smooth zoom is available and try to enable&disable.
TEST_F(CameraHidlTest,sendCommandSmoothZoom)2253 TEST_F(CameraHidlTest, sendCommandSmoothZoom) {
2254 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2255
2256 for (const auto& name : cameraDeviceNames) {
2257 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2258 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2259 openCameraDevice(name, mProvider, &device1 /*out*/);
2260 ASSERT_NE(nullptr, device1.get());
2261
2262 CameraParameters cameraParams;
2263 getParameters(device1, &cameraParams /*out*/);
2264
2265 const char* smoothZoomStr =
2266 cameraParams.get(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED);
2267 bool smoothZoomSupported =
2268 ((nullptr != smoothZoomStr) && (strcmp(smoothZoomStr, CameraParameters::TRUE) == 0))
2269 ? true
2270 : false;
2271 if (!smoothZoomSupported) {
2272 Return<void> ret = device1->close();
2273 ASSERT_TRUE(ret.isOk());
2274 continue;
2275 }
2276
2277 int32_t maxZoom = cameraParams.getInt(CameraParameters::KEY_MAX_ZOOM);
2278 ASSERT_TRUE(0 < maxZoom);
2279
2280 sp<BufferItemConsumer> bufferItemConsumer;
2281 sp<BufferItemHander> bufferHandler;
2282 setupPreviewWindow(device1, &bufferItemConsumer /*out*/, &bufferHandler /*out*/);
2283 startPreview(device1);
2284 setParameters(device1, cameraParams);
2285
2286 Return<Status> returnStatus =
2287 device1->sendCommand(CommandType::START_SMOOTH_ZOOM, maxZoom, 0);
2288 ASSERT_TRUE(returnStatus.isOk());
2289 ASSERT_EQ(Status::OK, returnStatus);
2290 // TODO(epeev) : Enable and check for face notifications
2291 returnStatus = device1->sendCommand(CommandType::STOP_SMOOTH_ZOOM, 0, 0);
2292 ASSERT_TRUE(returnStatus.isOk());
2293 ASSERT_EQ(Status::OK, returnStatus);
2294
2295 stopPreviewAndClose(device1);
2296 }
2297 }
2298 }
2299
2300 // Basic sanity tests related to camera parameters.
TEST_F(CameraHidlTest,getSetParameters)2301 TEST_F(CameraHidlTest, getSetParameters) {
2302 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2303
2304 for (const auto& name : cameraDeviceNames) {
2305 if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
2306 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2307 openCameraDevice(name, mProvider, &device1 /*out*/);
2308 ASSERT_NE(nullptr, device1.get());
2309
2310 CameraParameters cameraParams;
2311 getParameters(device1, &cameraParams /*out*/);
2312
2313 int32_t width, height;
2314 cameraParams.getPictureSize(&width, &height);
2315 ASSERT_TRUE((0 < width) && (0 < height));
2316 cameraParams.getPreviewSize(&width, &height);
2317 ASSERT_TRUE((0 < width) && (0 < height));
2318 int32_t minFps, maxFps;
2319 cameraParams.getPreviewFpsRange(&minFps, &maxFps);
2320 ASSERT_TRUE((0 < minFps) && (0 < maxFps));
2321 ASSERT_NE(nullptr, cameraParams.getPreviewFormat());
2322 ASSERT_NE(nullptr, cameraParams.getPictureFormat());
2323 ASSERT_TRUE(
2324 strcmp(CameraParameters::PIXEL_FORMAT_JPEG, cameraParams.getPictureFormat()) == 0);
2325
2326 const char* flashMode = cameraParams.get(CameraParameters::KEY_FLASH_MODE);
2327 ASSERT_TRUE((nullptr == flashMode) ||
2328 (strcmp(CameraParameters::FLASH_MODE_OFF, flashMode) == 0));
2329
2330 const char* wbMode = cameraParams.get(CameraParameters::KEY_WHITE_BALANCE);
2331 ASSERT_TRUE((nullptr == wbMode) ||
2332 (strcmp(CameraParameters::WHITE_BALANCE_AUTO, wbMode) == 0));
2333
2334 const char* effect = cameraParams.get(CameraParameters::KEY_EFFECT);
2335 ASSERT_TRUE((nullptr == effect) ||
2336 (strcmp(CameraParameters::EFFECT_NONE, effect) == 0));
2337
2338 ::android::Vector<Size> previewSizes;
2339 cameraParams.getSupportedPreviewSizes(previewSizes);
2340 ASSERT_FALSE(previewSizes.empty());
2341 ::android::Vector<Size> pictureSizes;
2342 cameraParams.getSupportedPictureSizes(pictureSizes);
2343 ASSERT_FALSE(pictureSizes.empty());
2344 const char* previewFormats =
2345 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
2346 ASSERT_NE(nullptr, previewFormats);
2347 ::android::String8 previewFormatsString(previewFormats);
2348 ASSERT_TRUE(previewFormatsString.contains(CameraParameters::PIXEL_FORMAT_YUV420SP));
2349 ASSERT_NE(nullptr, cameraParams.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
2350 ASSERT_NE(nullptr,
2351 cameraParams.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
2352 const char* focusModes = cameraParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
2353 ASSERT_NE(nullptr, focusModes);
2354 ::android::String8 focusModesString(focusModes);
2355 const char* focusMode = cameraParams.get(CameraParameters::KEY_FOCUS_MODE);
2356 ASSERT_NE(nullptr, focusMode);
2357 // Auto focus mode should be default
2358 if (focusModesString.contains(CameraParameters::FOCUS_MODE_AUTO)) {
2359 ASSERT_TRUE(strcmp(CameraParameters::FOCUS_MODE_AUTO, focusMode) == 0);
2360 }
2361 ASSERT_TRUE(0 < cameraParams.getInt(CameraParameters::KEY_FOCAL_LENGTH));
2362 int32_t horizontalViewAngle =
2363 cameraParams.getInt(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE);
2364 ASSERT_TRUE((0 < horizontalViewAngle) && (360 >= horizontalViewAngle));
2365 int32_t verticalViewAngle =
2366 cameraParams.getInt(CameraParameters::KEY_VERTICAL_VIEW_ANGLE);
2367 ASSERT_TRUE((0 < verticalViewAngle) && (360 >= verticalViewAngle));
2368 int32_t jpegQuality = cameraParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
2369 ASSERT_TRUE((1 <= jpegQuality) && (100 >= jpegQuality));
2370 int32_t jpegThumbQuality =
2371 cameraParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
2372 ASSERT_TRUE((1 <= jpegThumbQuality) && (100 >= jpegThumbQuality));
2373
2374 cameraParams.setPictureSize(pictureSizes[0].width, pictureSizes[0].height);
2375 cameraParams.setPreviewSize(previewSizes[0].width, previewSizes[0].height);
2376
2377 setParameters(device1, cameraParams);
2378 getParameters(device1, &cameraParams /*out*/);
2379
2380 cameraParams.getPictureSize(&width, &height);
2381 ASSERT_TRUE((pictureSizes[0].width == width) && (pictureSizes[0].height == height));
2382 cameraParams.getPreviewSize(&width, &height);
2383 ASSERT_TRUE((previewSizes[0].width == width) && (previewSizes[0].height == height));
2384
2385 Return<void> ret = device1->close();
2386 ASSERT_TRUE(ret.isOk());
2387 }
2388 }
2389 }
2390
2391 // Verify that the static camera characteristics can be retrieved
2392 // successfully.
TEST_F(CameraHidlTest,getCameraCharacteristics)2393 TEST_F(CameraHidlTest, getCameraCharacteristics) {
2394 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2395
2396 for (const auto& name : cameraDeviceNames) {
2397 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2398 switch (deviceVersion) {
2399 case CAMERA_DEVICE_API_VERSION_3_5:
2400 case CAMERA_DEVICE_API_VERSION_3_4:
2401 case CAMERA_DEVICE_API_VERSION_3_3:
2402 case CAMERA_DEVICE_API_VERSION_3_2: {
2403 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2404 ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str());
2405 Return<void> ret;
2406 ret = mProvider->getCameraDeviceInterface_V3_x(
2407 name, [&](auto status, const auto& device) {
2408 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2409 ASSERT_EQ(Status::OK, status);
2410 ASSERT_NE(device, nullptr);
2411 device3_x = device;
2412 });
2413 ASSERT_TRUE(ret.isOk());
2414
2415 ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) {
2416 verifyCameraCharacteristics(status, chars);
2417 verifyMonochromeCharacteristics(chars, deviceVersion);
2418 verifyRecommendedConfigs(chars);
2419 verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion,
2420 cameraDeviceNames);
2421 });
2422 ASSERT_TRUE(ret.isOk());
2423
2424 //getPhysicalCameraCharacteristics will fail for publicly
2425 //advertised camera IDs.
2426 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
2427 auto castResult = device::V3_5::ICameraDevice::castFrom(device3_x);
2428 ASSERT_TRUE(castResult.isOk());
2429 ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice>
2430 device3_5 = castResult;
2431 ASSERT_NE(device3_5, nullptr);
2432
2433 std::string version, cameraId;
2434 ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &cameraId));
2435 Return<void> ret = device3_5->getPhysicalCameraCharacteristics(cameraId,
2436 [&](auto status, const auto& chars) {
2437 ASSERT_TRUE(Status::ILLEGAL_ARGUMENT == status);
2438 ASSERT_EQ(0, chars.size());
2439 });
2440 ASSERT_TRUE(ret.isOk());
2441 }
2442 }
2443 break;
2444 case CAMERA_DEVICE_API_VERSION_1_0: {
2445 //Not applicable
2446 }
2447 break;
2448 default: {
2449 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2450 ADD_FAILURE();
2451 }
2452 break;
2453 }
2454 }
2455 }
2456
2457 //In case it is supported verify that torch can be enabled.
2458 //Check for corresponding toch callbacks as well.
TEST_F(CameraHidlTest,setTorchMode)2459 TEST_F(CameraHidlTest, setTorchMode) {
2460 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2461 bool torchControlSupported = false;
2462 Return<void> ret;
2463
2464 ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
2465 ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
2466 ASSERT_EQ(Status::OK, status);
2467 torchControlSupported = support;
2468 });
2469
2470 sp<TorchProviderCb> cb = new TorchProviderCb(this);
2471 Return<Status> returnStatus = mProvider->setCallback(cb);
2472 ASSERT_TRUE(returnStatus.isOk());
2473 ASSERT_EQ(Status::OK, returnStatus);
2474
2475 for (const auto& name : cameraDeviceNames) {
2476 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2477 switch (deviceVersion) {
2478 case CAMERA_DEVICE_API_VERSION_3_5:
2479 case CAMERA_DEVICE_API_VERSION_3_4:
2480 case CAMERA_DEVICE_API_VERSION_3_3:
2481 case CAMERA_DEVICE_API_VERSION_3_2: {
2482 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2483 ALOGI("setTorchMode: Testing camera device %s", name.c_str());
2484 ret = mProvider->getCameraDeviceInterface_V3_x(
2485 name, [&](auto status, const auto& device) {
2486 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2487 ASSERT_EQ(Status::OK, status);
2488 ASSERT_NE(device, nullptr);
2489 device3_x = device;
2490 });
2491 ASSERT_TRUE(ret.isOk());
2492
2493 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2494 returnStatus = device3_x->setTorchMode(TorchMode::ON);
2495 ASSERT_TRUE(returnStatus.isOk());
2496 if (!torchControlSupported) {
2497 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2498 } else {
2499 ASSERT_TRUE(returnStatus == Status::OK ||
2500 returnStatus == Status::OPERATION_NOT_SUPPORTED);
2501 if (returnStatus == Status::OK) {
2502 {
2503 std::unique_lock<std::mutex> l(mTorchLock);
2504 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2505 auto timeout = std::chrono::system_clock::now() +
2506 std::chrono::seconds(kTorchTimeoutSec);
2507 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2508 }
2509 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2510 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2511 }
2512
2513 returnStatus = device3_x->setTorchMode(TorchMode::OFF);
2514 ASSERT_TRUE(returnStatus.isOk());
2515 ASSERT_EQ(Status::OK, returnStatus);
2516
2517 {
2518 std::unique_lock<std::mutex> l(mTorchLock);
2519 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2520 auto timeout = std::chrono::system_clock::now() +
2521 std::chrono::seconds(kTorchTimeoutSec);
2522 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l, timeout));
2523 }
2524 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2525 }
2526 }
2527 }
2528 }
2529 break;
2530 case CAMERA_DEVICE_API_VERSION_1_0: {
2531 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2532 ALOGI("dumpState: Testing camera device %s", name.c_str());
2533 ret = mProvider->getCameraDeviceInterface_V1_x(
2534 name, [&](auto status, const auto& device) {
2535 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2536 ASSERT_EQ(Status::OK, status);
2537 ASSERT_NE(device, nullptr);
2538 device1 = device;
2539 });
2540 ASSERT_TRUE(ret.isOk());
2541
2542 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2543 returnStatus = device1->setTorchMode(TorchMode::ON);
2544 ASSERT_TRUE(returnStatus.isOk());
2545 if (!torchControlSupported) {
2546 ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
2547 } else {
2548 ASSERT_TRUE(returnStatus == Status::OK ||
2549 returnStatus == Status::OPERATION_NOT_SUPPORTED);
2550 if (returnStatus == Status::OK) {
2551 {
2552 std::unique_lock<std::mutex> l(mTorchLock);
2553 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2554 auto timeout = std::chrono::system_clock::now() +
2555 std::chrono::seconds(kTorchTimeoutSec);
2556 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2557 timeout));
2558 }
2559 ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
2560 mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
2561 }
2562
2563 returnStatus = device1->setTorchMode(TorchMode::OFF);
2564 ASSERT_TRUE(returnStatus.isOk());
2565 ASSERT_EQ(Status::OK, returnStatus);
2566
2567 {
2568 std::unique_lock<std::mutex> l(mTorchLock);
2569 while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
2570 auto timeout = std::chrono::system_clock::now() +
2571 std::chrono::seconds(kTorchTimeoutSec);
2572 ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
2573 timeout));
2574 }
2575 ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
2576 }
2577 }
2578 }
2579 ret = device1->close();
2580 ASSERT_TRUE(ret.isOk());
2581 }
2582 break;
2583 default: {
2584 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2585 ADD_FAILURE();
2586 }
2587 break;
2588 }
2589 }
2590
2591 returnStatus = mProvider->setCallback(nullptr);
2592 ASSERT_TRUE(returnStatus.isOk());
2593 ASSERT_EQ(Status::OK, returnStatus);
2594 }
2595
2596 // Check dump functionality.
TEST_F(CameraHidlTest,dumpState)2597 TEST_F(CameraHidlTest, dumpState) {
2598 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2599 Return<void> ret;
2600
2601 for (const auto& name : cameraDeviceNames) {
2602 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2603 switch (deviceVersion) {
2604 case CAMERA_DEVICE_API_VERSION_3_5:
2605 case CAMERA_DEVICE_API_VERSION_3_4:
2606 case CAMERA_DEVICE_API_VERSION_3_3:
2607 case CAMERA_DEVICE_API_VERSION_3_2: {
2608 ::android::sp<ICameraDevice> device3_x;
2609 ALOGI("dumpState: Testing camera device %s", name.c_str());
2610 ret = mProvider->getCameraDeviceInterface_V3_x(
2611 name, [&](auto status, const auto& device) {
2612 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2613 ASSERT_EQ(Status::OK, status);
2614 ASSERT_NE(device, nullptr);
2615 device3_x = device;
2616 });
2617 ASSERT_TRUE(ret.isOk());
2618
2619 native_handle_t* raw_handle = native_handle_create(1, 0);
2620 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2621 ASSERT_GE(raw_handle->data[0], 0);
2622 hidl_handle handle = raw_handle;
2623 ret = device3_x->dumpState(handle);
2624 ASSERT_TRUE(ret.isOk());
2625 close(raw_handle->data[0]);
2626 native_handle_delete(raw_handle);
2627 }
2628 break;
2629 case CAMERA_DEVICE_API_VERSION_1_0: {
2630 ::android::sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2631 ALOGI("dumpState: Testing camera device %s", name.c_str());
2632 ret = mProvider->getCameraDeviceInterface_V1_x(
2633 name, [&](auto status, const auto& device) {
2634 ALOGI("getCameraDeviceInterface_V1_x returns status:%d", (int)status);
2635 ASSERT_EQ(Status::OK, status);
2636 ASSERT_NE(device, nullptr);
2637 device1 = device;
2638 });
2639 ASSERT_TRUE(ret.isOk());
2640
2641 native_handle_t* raw_handle = native_handle_create(1, 0);
2642 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2643 ASSERT_GE(raw_handle->data[0], 0);
2644 hidl_handle handle = raw_handle;
2645 Return<Status> returnStatus = device1->dumpState(handle);
2646 ASSERT_TRUE(returnStatus.isOk());
2647 ASSERT_EQ(Status::OK, returnStatus);
2648 close(raw_handle->data[0]);
2649 native_handle_delete(raw_handle);
2650 }
2651 break;
2652 default: {
2653 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2654 ADD_FAILURE();
2655 }
2656 break;
2657 }
2658 }
2659 }
2660
2661 // Open, dumpStates, then close
TEST_F(CameraHidlTest,openClose)2662 TEST_F(CameraHidlTest, openClose) {
2663 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2664 Return<void> ret;
2665
2666 for (const auto& name : cameraDeviceNames) {
2667 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2668 switch (deviceVersion) {
2669 case CAMERA_DEVICE_API_VERSION_3_5:
2670 case CAMERA_DEVICE_API_VERSION_3_4:
2671 case CAMERA_DEVICE_API_VERSION_3_3:
2672 case CAMERA_DEVICE_API_VERSION_3_2: {
2673 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2674 ALOGI("openClose: Testing camera device %s", name.c_str());
2675 ret = mProvider->getCameraDeviceInterface_V3_x(
2676 name, [&](auto status, const auto& device) {
2677 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2678 ASSERT_EQ(Status::OK, status);
2679 ASSERT_NE(device, nullptr);
2680 device3_x = device;
2681 });
2682 ASSERT_TRUE(ret.isOk());
2683
2684 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2685 sp<ICameraDeviceSession> session;
2686 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2687 ALOGI("device::open returns status:%d", (int)status);
2688 ASSERT_EQ(Status::OK, status);
2689 ASSERT_NE(newSession, nullptr);
2690 session = newSession;
2691 });
2692 ASSERT_TRUE(ret.isOk());
2693 // Ensure that a device labeling itself as 3.3/3.4 can have its session interface
2694 // cast the 3.3/3.4 interface, and that lower versions can't be cast to it.
2695 sp<device::V3_3::ICameraDeviceSession> sessionV3_3;
2696 sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
2697 sp<device::V3_5::ICameraDeviceSession> sessionV3_5;
2698 castSession(session, deviceVersion, &sessionV3_3, &sessionV3_4, &sessionV3_5);
2699 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
2700 ASSERT_TRUE(sessionV3_5.get() != nullptr);
2701 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
2702 ASSERT_TRUE(sessionV3_4.get() != nullptr);
2703 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_3) {
2704 ASSERT_TRUE(sessionV3_3.get() != nullptr);
2705 } else { //V3_2
2706 ASSERT_TRUE(sessionV3_3.get() == nullptr);
2707 ASSERT_TRUE(sessionV3_4.get() == nullptr);
2708 ASSERT_TRUE(sessionV3_5.get() == nullptr);
2709 }
2710 native_handle_t* raw_handle = native_handle_create(1, 0);
2711 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2712 ASSERT_GE(raw_handle->data[0], 0);
2713 hidl_handle handle = raw_handle;
2714 ret = device3_x->dumpState(handle);
2715 ASSERT_TRUE(ret.isOk());
2716 close(raw_handle->data[0]);
2717 native_handle_delete(raw_handle);
2718
2719 ret = session->close();
2720 ASSERT_TRUE(ret.isOk());
2721 // TODO: test all session API calls return INTERNAL_ERROR after close
2722 // TODO: keep a wp copy here and verify session cannot be promoted out of this scope
2723 }
2724 break;
2725 case CAMERA_DEVICE_API_VERSION_1_0: {
2726 sp<::android::hardware::camera::device::V1_0::ICameraDevice> device1;
2727 openCameraDevice(name, mProvider, &device1 /*out*/);
2728 ASSERT_NE(nullptr, device1.get());
2729
2730 native_handle_t* raw_handle = native_handle_create(1, 0);
2731 raw_handle->data[0] = open(kDumpOutput, O_RDWR);
2732 ASSERT_GE(raw_handle->data[0], 0);
2733 hidl_handle handle = raw_handle;
2734 Return<Status> returnStatus = device1->dumpState(handle);
2735 ASSERT_TRUE(returnStatus.isOk());
2736 ASSERT_EQ(Status::OK, returnStatus);
2737 close(raw_handle->data[0]);
2738 native_handle_delete(raw_handle);
2739
2740 ret = device1->close();
2741 ASSERT_TRUE(ret.isOk());
2742 }
2743 break;
2744 default: {
2745 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2746 ADD_FAILURE();
2747 }
2748 break;
2749 }
2750 }
2751 }
2752
2753 // Check whether all common default request settings can be sucessfully
2754 // constructed.
TEST_F(CameraHidlTest,constructDefaultRequestSettings)2755 TEST_F(CameraHidlTest, constructDefaultRequestSettings) {
2756 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2757
2758 for (const auto& name : cameraDeviceNames) {
2759 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2760 switch (deviceVersion) {
2761 case CAMERA_DEVICE_API_VERSION_3_5:
2762 case CAMERA_DEVICE_API_VERSION_3_4:
2763 case CAMERA_DEVICE_API_VERSION_3_3:
2764 case CAMERA_DEVICE_API_VERSION_3_2: {
2765 ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x;
2766 Return<void> ret;
2767 ALOGI("constructDefaultRequestSettings: Testing camera device %s", name.c_str());
2768 ret = mProvider->getCameraDeviceInterface_V3_x(
2769 name, [&](auto status, const auto& device) {
2770 ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
2771 ASSERT_EQ(Status::OK, status);
2772 ASSERT_NE(device, nullptr);
2773 device3_x = device;
2774 });
2775 ASSERT_TRUE(ret.isOk());
2776
2777 sp<EmptyDeviceCb> cb = new EmptyDeviceCb;
2778 sp<ICameraDeviceSession> session;
2779 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
2780 ALOGI("device::open returns status:%d", (int)status);
2781 ASSERT_EQ(Status::OK, status);
2782 ASSERT_NE(newSession, nullptr);
2783 session = newSession;
2784 });
2785 ASSERT_TRUE(ret.isOk());
2786
2787 for (uint32_t t = (uint32_t)RequestTemplate::PREVIEW;
2788 t <= (uint32_t)RequestTemplate::MANUAL; t++) {
2789 RequestTemplate reqTemplate = (RequestTemplate)t;
2790 ret =
2791 session->constructDefaultRequestSettings(
2792 reqTemplate, [&](auto status, const auto& req) {
2793 ALOGI("constructDefaultRequestSettings returns status:%d",
2794 (int)status);
2795 if (reqTemplate == RequestTemplate::ZERO_SHUTTER_LAG ||
2796 reqTemplate == RequestTemplate::MANUAL) {
2797 // optional templates
2798 ASSERT_TRUE((status == Status::OK) ||
2799 (status == Status::ILLEGAL_ARGUMENT));
2800 } else {
2801 ASSERT_EQ(Status::OK, status);
2802 }
2803
2804 if (status == Status::OK) {
2805 const camera_metadata_t* metadata =
2806 (camera_metadata_t*) req.data();
2807 size_t expectedSize = req.size();
2808 int result = validate_camera_metadata_structure(
2809 metadata, &expectedSize);
2810 ASSERT_TRUE((result == 0) ||
2811 (result == CAMERA_METADATA_VALIDATION_SHIFTED));
2812 size_t entryCount =
2813 get_camera_metadata_entry_count(metadata);
2814 // TODO: we can do better than 0 here. Need to check how many required
2815 // request keys we've defined for each template
2816 ASSERT_GT(entryCount, 0u);
2817 ALOGI("template %u metadata entry count is %zu",
2818 t, entryCount);
2819 } else {
2820 ASSERT_EQ(0u, req.size());
2821 }
2822 });
2823 ASSERT_TRUE(ret.isOk());
2824 }
2825 ret = session->close();
2826 ASSERT_TRUE(ret.isOk());
2827 }
2828 break;
2829 case CAMERA_DEVICE_API_VERSION_1_0: {
2830 //Not applicable
2831 }
2832 break;
2833 default: {
2834 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2835 ADD_FAILURE();
2836 }
2837 break;
2838 }
2839 }
2840 }
2841
2842
2843 // Verify that all supported stream formats and sizes can be configured
2844 // successfully.
TEST_F(CameraHidlTest,configureStreamsAvailableOutputs)2845 TEST_F(CameraHidlTest, configureStreamsAvailableOutputs) {
2846 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2847 std::vector<AvailableStream> outputStreams;
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 sp<device::V3_5::ICameraDeviceSession> session3_5;
2865 sp<device::V3_2::ICameraDevice> cameraDevice;
2866 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
2867 openEmptyDeviceSession(name, mProvider,
2868 &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
2869 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
2870 castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
2871
2872 outputStreams.clear();
2873 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2874 ASSERT_NE(0u, outputStreams.size());
2875
2876 uint32_t jpegBufferSize = 0;
2877 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
2878 ASSERT_NE(0u, jpegBufferSize);
2879
2880 int32_t streamId = 0;
2881 uint32_t streamConfigCounter = 0;
2882 for (auto& it : outputStreams) {
2883 V3_2::Stream stream3_2;
2884 V3_2::DataspaceFlags dataspaceFlag = 0;
2885 switch (static_cast<PixelFormat>(it.format)) {
2886 case PixelFormat::BLOB:
2887 dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
2888 break;
2889 case PixelFormat::Y16:
2890 dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
2891 break;
2892 default:
2893 dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
2894 }
2895 stream3_2 = {streamId,
2896 StreamType::OUTPUT,
2897 static_cast<uint32_t>(it.width),
2898 static_cast<uint32_t>(it.height),
2899 static_cast<PixelFormat>(it.format),
2900 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2901 dataspaceFlag,
2902 StreamRotation::ROTATION_0};
2903 ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
2904 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
2905 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
2906 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
2907 createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
2908 &config3_2, &config3_4, &config3_5, jpegBufferSize);
2909 if (session3_5 != nullptr) {
2910 bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
2911 verifyStreamCombination(cameraDevice3_5, config3_4,
2912 /*expectedStatus*/ true, expectStreamCombQuery);
2913 config3_5.streamConfigCounter = streamConfigCounter++;
2914 ret = session3_5->configureStreams_3_5(config3_5,
2915 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2916 ASSERT_EQ(Status::OK, s);
2917 ASSERT_EQ(1u, halConfig.streams.size());
2918 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
2919 });
2920 } else if (session3_4 != nullptr) {
2921 ret = session3_4->configureStreams_3_4(config3_4,
2922 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
2923 ASSERT_EQ(Status::OK, s);
2924 ASSERT_EQ(1u, halConfig.streams.size());
2925 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
2926 });
2927 } else if (session3_3 != nullptr) {
2928 ret = session3_3->configureStreams_3_3(config3_2,
2929 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
2930 ASSERT_EQ(Status::OK, s);
2931 ASSERT_EQ(1u, halConfig.streams.size());
2932 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
2933 });
2934 } else {
2935 ret = session->configureStreams(config3_2,
2936 [streamId](Status s, HalStreamConfiguration halConfig) {
2937 ASSERT_EQ(Status::OK, s);
2938 ASSERT_EQ(1u, halConfig.streams.size());
2939 ASSERT_EQ(halConfig.streams[0].id, streamId);
2940 });
2941 }
2942 ASSERT_TRUE(ret.isOk());
2943 streamId++;
2944 }
2945
2946 free_camera_metadata(staticMeta);
2947 ret = session->close();
2948 ASSERT_TRUE(ret.isOk());
2949 }
2950 }
2951
2952 // Check for correct handling of invalid/incorrect configuration parameters.
TEST_F(CameraHidlTest,configureStreamsInvalidOutputs)2953 TEST_F(CameraHidlTest, configureStreamsInvalidOutputs) {
2954 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
2955 std::vector<AvailableStream> outputStreams;
2956
2957 for (const auto& name : cameraDeviceNames) {
2958 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
2959 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
2960 continue;
2961 } else if (deviceVersion <= 0) {
2962 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
2963 ADD_FAILURE();
2964 return;
2965 }
2966
2967 camera_metadata_t* staticMeta;
2968 Return<void> ret;
2969 sp<ICameraDeviceSession> session;
2970 sp<device::V3_3::ICameraDeviceSession> session3_3;
2971 sp<device::V3_4::ICameraDeviceSession> session3_4;
2972 sp<device::V3_5::ICameraDeviceSession> session3_5;
2973 sp<device::V3_2::ICameraDevice> cameraDevice;
2974 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
2975 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
2976 &cameraDevice /*out*/);
2977 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
2978 castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
2979
2980 outputStreams.clear();
2981 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
2982 ASSERT_NE(0u, outputStreams.size());
2983
2984 uint32_t jpegBufferSize = 0;
2985 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
2986 ASSERT_NE(0u, jpegBufferSize);
2987
2988 int32_t streamId = 0;
2989 V3_2::Stream stream3_2 = {streamId++,
2990 StreamType::OUTPUT,
2991 static_cast<uint32_t>(0),
2992 static_cast<uint32_t>(0),
2993 static_cast<PixelFormat>(outputStreams[0].format),
2994 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
2995 0,
2996 StreamRotation::ROTATION_0};
2997 uint32_t streamConfigCounter = 0;
2998 ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream3_2};
2999 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3000 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3001 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3002 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3003 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3004 if (session3_5 != nullptr) {
3005 verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false,
3006 /*expectStreamCombQuery*/false);
3007 config3_5.streamConfigCounter = streamConfigCounter++;
3008 ret = session3_5->configureStreams_3_5(config3_5,
3009 [](Status s, device::V3_4::HalStreamConfiguration) {
3010 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3011 (Status::INTERNAL_ERROR == s));
3012 });
3013 } else if (session3_4 != nullptr) {
3014 ret = session3_4->configureStreams_3_4(config3_4,
3015 [](Status s, device::V3_4::HalStreamConfiguration) {
3016 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3017 (Status::INTERNAL_ERROR == s));
3018 });
3019 } else if(session3_3 != nullptr) {
3020 ret = session3_3->configureStreams_3_3(config3_2,
3021 [](Status s, device::V3_3::HalStreamConfiguration) {
3022 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3023 (Status::INTERNAL_ERROR == s));
3024 });
3025 } else {
3026 ret = session->configureStreams(config3_2,
3027 [](Status s, HalStreamConfiguration) {
3028 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3029 (Status::INTERNAL_ERROR == s));
3030 });
3031 }
3032 ASSERT_TRUE(ret.isOk());
3033
3034 stream3_2 = {streamId++,
3035 StreamType::OUTPUT,
3036 static_cast<uint32_t>(UINT32_MAX),
3037 static_cast<uint32_t>(UINT32_MAX),
3038 static_cast<PixelFormat>(outputStreams[0].format),
3039 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3040 0,
3041 StreamRotation::ROTATION_0};
3042 streams[0] = stream3_2;
3043 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3044 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3045 if (session3_5 != nullptr) {
3046 config3_5.streamConfigCounter = streamConfigCounter++;
3047 ret = session3_5->configureStreams_3_5(config3_5, [](Status s,
3048 device::V3_4::HalStreamConfiguration) {
3049 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3050 });
3051 } else if(session3_4 != nullptr) {
3052 ret = session3_4->configureStreams_3_4(config3_4, [](Status s,
3053 device::V3_4::HalStreamConfiguration) {
3054 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3055 });
3056 } else if(session3_3 != nullptr) {
3057 ret = session3_3->configureStreams_3_3(config3_2, [](Status s,
3058 device::V3_3::HalStreamConfiguration) {
3059 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3060 });
3061 } else {
3062 ret = session->configureStreams(config3_2, [](Status s,
3063 HalStreamConfiguration) {
3064 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3065 });
3066 }
3067 ASSERT_TRUE(ret.isOk());
3068
3069 for (auto& it : outputStreams) {
3070 stream3_2 = {streamId++,
3071 StreamType::OUTPUT,
3072 static_cast<uint32_t>(it.width),
3073 static_cast<uint32_t>(it.height),
3074 static_cast<PixelFormat>(UINT32_MAX),
3075 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3076 0,
3077 StreamRotation::ROTATION_0};
3078 streams[0] = stream3_2;
3079 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3080 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3081 if (session3_5 != nullptr) {
3082 config3_5.streamConfigCounter = streamConfigCounter++;
3083 ret = session3_5->configureStreams_3_5(config3_5,
3084 [](Status s, device::V3_4::HalStreamConfiguration) {
3085 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3086 });
3087 } else if(session3_4 != nullptr) {
3088 ret = session3_4->configureStreams_3_4(config3_4,
3089 [](Status s, device::V3_4::HalStreamConfiguration) {
3090 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3091 });
3092 } else if(session3_3 != nullptr) {
3093 ret = session3_3->configureStreams_3_3(config3_2,
3094 [](Status s, device::V3_3::HalStreamConfiguration) {
3095 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3096 });
3097 } else {
3098 ret = session->configureStreams(config3_2,
3099 [](Status s, HalStreamConfiguration) {
3100 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3101 });
3102 }
3103 ASSERT_TRUE(ret.isOk());
3104
3105 stream3_2 = {streamId++,
3106 StreamType::OUTPUT,
3107 static_cast<uint32_t>(it.width),
3108 static_cast<uint32_t>(it.height),
3109 static_cast<PixelFormat>(it.format),
3110 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3111 0,
3112 static_cast<StreamRotation>(UINT32_MAX)};
3113 streams[0] = stream3_2;
3114 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3115 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3116 if (session3_5 != nullptr) {
3117 config3_5.streamConfigCounter = streamConfigCounter++;
3118 ret = session3_5->configureStreams_3_5(config3_5,
3119 [](Status s, device::V3_4::HalStreamConfiguration) {
3120 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3121 });
3122 } else if(session3_4 != nullptr) {
3123 ret = session3_4->configureStreams_3_4(config3_4,
3124 [](Status s, device::V3_4::HalStreamConfiguration) {
3125 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3126 });
3127 } else if(session3_3 != nullptr) {
3128 ret = session3_3->configureStreams_3_3(config3_2,
3129 [](Status s, device::V3_3::HalStreamConfiguration) {
3130 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3131 });
3132 } else {
3133 ret = session->configureStreams(config3_2,
3134 [](Status s, HalStreamConfiguration) {
3135 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3136 });
3137 }
3138 ASSERT_TRUE(ret.isOk());
3139 }
3140
3141 free_camera_metadata(staticMeta);
3142 ret = session->close();
3143 ASSERT_TRUE(ret.isOk());
3144 }
3145 }
3146
3147 // Check whether all supported ZSL output stream combinations can be
3148 // configured successfully.
TEST_F(CameraHidlTest,configureStreamsZSLInputOutputs)3149 TEST_F(CameraHidlTest, configureStreamsZSLInputOutputs) {
3150 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3151 std::vector<AvailableStream> inputStreams;
3152 std::vector<AvailableZSLInputOutput> inputOutputMap;
3153
3154 for (const auto& name : cameraDeviceNames) {
3155 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3156 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3157 continue;
3158 } else if (deviceVersion <= 0) {
3159 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3160 ADD_FAILURE();
3161 return;
3162 }
3163
3164 camera_metadata_t* staticMeta;
3165 Return<void> ret;
3166 sp<ICameraDeviceSession> session;
3167 sp<device::V3_3::ICameraDeviceSession> session3_3;
3168 sp<device::V3_4::ICameraDeviceSession> session3_4;
3169 sp<device::V3_5::ICameraDeviceSession> session3_5;
3170 sp<device::V3_2::ICameraDevice> cameraDevice;
3171 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3172 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3173 &cameraDevice /*out*/);
3174 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3175 castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3176
3177 Status rc = isZSLModeAvailable(staticMeta);
3178 if (Status::METHOD_NOT_SUPPORTED == rc) {
3179 ret = session->close();
3180 ASSERT_TRUE(ret.isOk());
3181 continue;
3182 }
3183 ASSERT_EQ(Status::OK, rc);
3184
3185 inputStreams.clear();
3186 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, inputStreams));
3187 ASSERT_NE(0u, inputStreams.size());
3188
3189 inputOutputMap.clear();
3190 ASSERT_EQ(Status::OK, getZSLInputOutputMap(staticMeta, inputOutputMap));
3191 ASSERT_NE(0u, inputOutputMap.size());
3192
3193 bool supportMonoY8 = false;
3194 if (Status::OK == isMonochromeCamera(staticMeta)) {
3195 for (auto& it : inputStreams) {
3196 if (it.format == static_cast<uint32_t>(PixelFormat::Y8)) {
3197 supportMonoY8 = true;
3198 break;
3199 }
3200 }
3201 }
3202
3203 uint32_t jpegBufferSize = 0;
3204 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
3205 ASSERT_NE(0u, jpegBufferSize);
3206
3207 int32_t streamId = 0;
3208 bool hasPrivToY8 = false, hasY8ToY8 = false, hasY8ToBlob = false;
3209 uint32_t streamConfigCounter = 0;
3210 for (auto& inputIter : inputOutputMap) {
3211 AvailableStream input;
3212 ASSERT_EQ(Status::OK, findLargestSize(inputStreams, inputIter.inputFormat,
3213 input));
3214 ASSERT_NE(0u, inputStreams.size());
3215
3216 if (inputIter.inputFormat == static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)
3217 && inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
3218 hasPrivToY8 = true;
3219 } else if (inputIter.inputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
3220 if (inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::BLOB)) {
3221 hasY8ToBlob = true;
3222 } else if (inputIter.outputFormat == static_cast<uint32_t>(PixelFormat::Y8)) {
3223 hasY8ToY8 = true;
3224 }
3225 }
3226 AvailableStream outputThreshold = {INT32_MAX, INT32_MAX,
3227 inputIter.outputFormat};
3228 std::vector<AvailableStream> outputStreams;
3229 ASSERT_EQ(Status::OK,
3230 getAvailableOutputStreams(staticMeta, outputStreams,
3231 &outputThreshold));
3232 for (auto& outputIter : outputStreams) {
3233 V3_2::Stream zslStream = {streamId++,
3234 StreamType::OUTPUT,
3235 static_cast<uint32_t>(input.width),
3236 static_cast<uint32_t>(input.height),
3237 static_cast<PixelFormat>(input.format),
3238 GRALLOC_USAGE_HW_CAMERA_ZSL,
3239 0,
3240 StreamRotation::ROTATION_0};
3241 V3_2::Stream inputStream = {streamId++,
3242 StreamType::INPUT,
3243 static_cast<uint32_t>(input.width),
3244 static_cast<uint32_t>(input.height),
3245 static_cast<PixelFormat>(input.format),
3246 0,
3247 0,
3248 StreamRotation::ROTATION_0};
3249 V3_2::Stream outputStream = {streamId++,
3250 StreamType::OUTPUT,
3251 static_cast<uint32_t>(outputIter.width),
3252 static_cast<uint32_t>(outputIter.height),
3253 static_cast<PixelFormat>(outputIter.format),
3254 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3255 0,
3256 StreamRotation::ROTATION_0};
3257
3258 ::android::hardware::hidl_vec<V3_2::Stream> streams = {inputStream, zslStream,
3259 outputStream};
3260 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3261 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3262 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3263 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3264 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3265 if (session3_5 != nullptr) {
3266 verifyStreamCombination(cameraDevice3_5, config3_4,
3267 /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3268 config3_5.streamConfigCounter = streamConfigCounter++;
3269 ret = session3_5->configureStreams_3_5(config3_5,
3270 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3271 ASSERT_EQ(Status::OK, s);
3272 ASSERT_EQ(3u, halConfig.streams.size());
3273 });
3274 } else if (session3_4 != nullptr) {
3275 ret = session3_4->configureStreams_3_4(config3_4,
3276 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3277 ASSERT_EQ(Status::OK, s);
3278 ASSERT_EQ(3u, halConfig.streams.size());
3279 });
3280 } else if (session3_3 != nullptr) {
3281 ret = session3_3->configureStreams_3_3(config3_2,
3282 [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3283 ASSERT_EQ(Status::OK, s);
3284 ASSERT_EQ(3u, halConfig.streams.size());
3285 });
3286 } else {
3287 ret = session->configureStreams(config3_2,
3288 [](Status s, HalStreamConfiguration halConfig) {
3289 ASSERT_EQ(Status::OK, s);
3290 ASSERT_EQ(3u, halConfig.streams.size());
3291 });
3292 }
3293 ASSERT_TRUE(ret.isOk());
3294 }
3295 }
3296
3297 if (supportMonoY8) {
3298 if (Status::OK == isZSLModeAvailable(staticMeta, PRIV_REPROCESS)) {
3299 ASSERT_TRUE(hasPrivToY8);
3300 }
3301 if (Status::OK == isZSLModeAvailable(staticMeta, YUV_REPROCESS)) {
3302 ASSERT_TRUE(hasY8ToY8);
3303 ASSERT_TRUE(hasY8ToBlob);
3304 }
3305 }
3306
3307 free_camera_metadata(staticMeta);
3308 ret = session->close();
3309 ASSERT_TRUE(ret.isOk());
3310 }
3311 }
3312
3313 // Check whether session parameters are supported. If Hal support for them
3314 // exist, then try to configure a preview stream using them.
TEST_F(CameraHidlTest,configureStreamsWithSessionParameters)3315 TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) {
3316 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3317 std::vector<AvailableStream> outputPreviewStreams;
3318 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3319 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3320
3321 for (const auto& name : cameraDeviceNames) {
3322 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3323 if (deviceVersion <= 0) {
3324 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3325 ADD_FAILURE();
3326 return;
3327 } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_4) {
3328 continue;
3329 }
3330
3331 camera_metadata_t* staticMetaBuffer;
3332 Return<void> ret;
3333 sp<ICameraDeviceSession> session;
3334 sp<device::V3_3::ICameraDeviceSession> session3_3;
3335 sp<device::V3_4::ICameraDeviceSession> session3_4;
3336 sp<device::V3_5::ICameraDeviceSession> session3_5;
3337 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
3338 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3339 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
3340 ASSERT_NE(session3_4, nullptr);
3341 } else {
3342 ASSERT_NE(session3_5, nullptr);
3343 }
3344
3345 std::unordered_set<int32_t> availableSessionKeys;
3346 auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS,
3347 &availableSessionKeys);
3348 ASSERT_TRUE(Status::OK == rc);
3349 if (availableSessionKeys.empty()) {
3350 free_camera_metadata(staticMetaBuffer);
3351 ret = session->close();
3352 ASSERT_TRUE(ret.isOk());
3353 continue;
3354 }
3355
3356 android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
3357 android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams,
3358 modifiedSessionParams;
3359 constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW,
3360 &previewRequestSettings, &sessionParams);
3361 if (sessionParams.isEmpty()) {
3362 free_camera_metadata(staticMetaBuffer);
3363 ret = session->close();
3364 ASSERT_TRUE(ret.isOk());
3365 continue;
3366 }
3367
3368 outputPreviewStreams.clear();
3369
3370 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams,
3371 &previewThreshold));
3372 ASSERT_NE(0u, outputPreviewStreams.size());
3373
3374 V3_4::Stream previewStream;
3375 previewStream.v3_2 = {0,
3376 StreamType::OUTPUT,
3377 static_cast<uint32_t>(outputPreviewStreams[0].width),
3378 static_cast<uint32_t>(outputPreviewStreams[0].height),
3379 static_cast<PixelFormat>(outputPreviewStreams[0].format),
3380 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3381 0,
3382 StreamRotation::ROTATION_0};
3383 previewStream.bufferSize = 0;
3384 ::android::hardware::hidl_vec<V3_4::Stream> streams = {previewStream};
3385 ::android::hardware::camera::device::V3_4::StreamConfiguration config;
3386 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3387 config.streams = streams;
3388 config.operationMode = StreamConfigurationMode::NORMAL_MODE;
3389 modifiedSessionParams = sessionParams;
3390 auto sessionParamsBuffer = sessionParams.release();
3391 config.sessionParams.setToExternal(reinterpret_cast<uint8_t *> (sessionParamsBuffer),
3392 get_camera_metadata_size(sessionParamsBuffer));
3393 config3_5.v3_4 = config;
3394 config3_5.streamConfigCounter = 0;
3395 if (session3_5 != nullptr) {
3396 bool newSessionParamsAvailable = false;
3397 for (const auto& it : availableSessionKeys) {
3398 if (modifiedSessionParams.exists(it)) {
3399 modifiedSessionParams.erase(it);
3400 newSessionParamsAvailable = true;
3401 break;
3402 }
3403 }
3404 if (newSessionParamsAvailable) {
3405 auto modifiedSessionParamsBuffer = modifiedSessionParams.release();
3406 verifySessionReconfigurationQuery(session3_5, sessionParamsBuffer,
3407 modifiedSessionParamsBuffer);
3408 modifiedSessionParams.acquire(modifiedSessionParamsBuffer);
3409 }
3410
3411 ret = session3_5->configureStreams_3_5(config3_5,
3412 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3413 ASSERT_EQ(Status::OK, s);
3414 ASSERT_EQ(1u, halConfig.streams.size());
3415 });
3416 } else {
3417 ret = session3_4->configureStreams_3_4(config,
3418 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3419 ASSERT_EQ(Status::OK, s);
3420 ASSERT_EQ(1u, halConfig.streams.size());
3421 });
3422 }
3423 sessionParams.acquire(sessionParamsBuffer);
3424 ASSERT_TRUE(ret.isOk());
3425
3426 free_camera_metadata(staticMetaBuffer);
3427 ret = session->close();
3428 ASSERT_TRUE(ret.isOk());
3429 }
3430 }
3431
3432 // Verify that all supported preview + still capture stream combinations
3433 // can be configured successfully.
TEST_F(CameraHidlTest,configureStreamsPreviewStillOutputs)3434 TEST_F(CameraHidlTest, configureStreamsPreviewStillOutputs) {
3435 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3436 std::vector<AvailableStream> outputBlobStreams;
3437 std::vector<AvailableStream> outputPreviewStreams;
3438 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3439 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3440 AvailableStream blobThreshold = {INT32_MAX, INT32_MAX,
3441 static_cast<int32_t>(PixelFormat::BLOB)};
3442
3443 for (const auto& name : cameraDeviceNames) {
3444 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3445 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3446 continue;
3447 } else if (deviceVersion <= 0) {
3448 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3449 ADD_FAILURE();
3450 return;
3451 }
3452
3453 camera_metadata_t* staticMeta;
3454 Return<void> ret;
3455 sp<ICameraDeviceSession> session;
3456 sp<device::V3_3::ICameraDeviceSession> session3_3;
3457 sp<device::V3_4::ICameraDeviceSession> session3_4;
3458 sp<device::V3_5::ICameraDeviceSession> session3_5;
3459 sp<device::V3_2::ICameraDevice> cameraDevice;
3460 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3461 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3462 &cameraDevice /*out*/);
3463 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3464 castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3465
3466 // Check if camera support depth only
3467 if (isDepthOnly(staticMeta)) {
3468 free_camera_metadata(staticMeta);
3469 ret = session->close();
3470 ASSERT_TRUE(ret.isOk());
3471 continue;
3472 }
3473
3474 outputBlobStreams.clear();
3475 ASSERT_EQ(Status::OK,
3476 getAvailableOutputStreams(staticMeta, outputBlobStreams,
3477 &blobThreshold));
3478 ASSERT_NE(0u, outputBlobStreams.size());
3479
3480 outputPreviewStreams.clear();
3481 ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputPreviewStreams,
3482 &previewThreshold));
3483 ASSERT_NE(0u, outputPreviewStreams.size());
3484
3485 uint32_t jpegBufferSize = 0;
3486 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
3487 ASSERT_NE(0u, jpegBufferSize);
3488
3489 int32_t streamId = 0;
3490 uint32_t streamConfigCounter = 0;
3491 for (auto& blobIter : outputBlobStreams) {
3492 for (auto& previewIter : outputPreviewStreams) {
3493 V3_2::Stream previewStream = {streamId++,
3494 StreamType::OUTPUT,
3495 static_cast<uint32_t>(previewIter.width),
3496 static_cast<uint32_t>(previewIter.height),
3497 static_cast<PixelFormat>(previewIter.format),
3498 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
3499 0,
3500 StreamRotation::ROTATION_0};
3501 V3_2::Stream blobStream = {streamId++,
3502 StreamType::OUTPUT,
3503 static_cast<uint32_t>(blobIter.width),
3504 static_cast<uint32_t>(blobIter.height),
3505 static_cast<PixelFormat>(blobIter.format),
3506 GRALLOC1_CONSUMER_USAGE_CPU_READ,
3507 static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF),
3508 StreamRotation::ROTATION_0};
3509 ::android::hardware::hidl_vec<V3_2::Stream> streams = {previewStream,
3510 blobStream};
3511 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3512 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3513 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3514 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3515 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3516 if (session3_5 != nullptr) {
3517 verifyStreamCombination(cameraDevice3_5, config3_4,
3518 /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3519 config3_5.streamConfigCounter = streamConfigCounter++;
3520 ret = session3_5->configureStreams_3_5(config3_5,
3521 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3522 ASSERT_EQ(Status::OK, s);
3523 ASSERT_EQ(2u, halConfig.streams.size());
3524 });
3525 } else if (session3_4 != nullptr) {
3526 ret = session3_4->configureStreams_3_4(config3_4,
3527 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3528 ASSERT_EQ(Status::OK, s);
3529 ASSERT_EQ(2u, halConfig.streams.size());
3530 });
3531 } else if (session3_3 != nullptr) {
3532 ret = session3_3->configureStreams_3_3(config3_2,
3533 [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3534 ASSERT_EQ(Status::OK, s);
3535 ASSERT_EQ(2u, halConfig.streams.size());
3536 });
3537 } else {
3538 ret = session->configureStreams(config3_2,
3539 [](Status s, HalStreamConfiguration halConfig) {
3540 ASSERT_EQ(Status::OK, s);
3541 ASSERT_EQ(2u, halConfig.streams.size());
3542 });
3543 }
3544 ASSERT_TRUE(ret.isOk());
3545 }
3546 }
3547
3548 free_camera_metadata(staticMeta);
3549 ret = session->close();
3550 ASSERT_TRUE(ret.isOk());
3551 }
3552 }
3553
3554 // In case constrained mode is supported, test whether it can be
3555 // configured. Additionally check for common invalid inputs when
3556 // using this mode.
TEST_F(CameraHidlTest,configureStreamsConstrainedOutputs)3557 TEST_F(CameraHidlTest, configureStreamsConstrainedOutputs) {
3558 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3559
3560 for (const auto& name : cameraDeviceNames) {
3561 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3562 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3563 continue;
3564 } else if (deviceVersion <= 0) {
3565 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3566 ADD_FAILURE();
3567 return;
3568 }
3569
3570 camera_metadata_t* staticMeta;
3571 Return<void> ret;
3572 sp<ICameraDeviceSession> session;
3573 sp<device::V3_3::ICameraDeviceSession> session3_3;
3574 sp<device::V3_4::ICameraDeviceSession> session3_4;
3575 sp<device::V3_5::ICameraDeviceSession> session3_5;
3576 sp<device::V3_2::ICameraDevice> cameraDevice;
3577 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3578 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3579 &cameraDevice /*out*/);
3580 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3581 castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3582
3583 Status rc = isConstrainedModeAvailable(staticMeta);
3584 if (Status::METHOD_NOT_SUPPORTED == rc) {
3585 ret = session->close();
3586 ASSERT_TRUE(ret.isOk());
3587 continue;
3588 }
3589 ASSERT_EQ(Status::OK, rc);
3590
3591 AvailableStream hfrStream;
3592 rc = pickConstrainedModeSize(staticMeta, hfrStream);
3593 ASSERT_EQ(Status::OK, rc);
3594
3595 int32_t streamId = 0;
3596 uint32_t streamConfigCounter = 0;
3597 V3_2::Stream stream = {streamId,
3598 StreamType::OUTPUT,
3599 static_cast<uint32_t>(hfrStream.width),
3600 static_cast<uint32_t>(hfrStream.height),
3601 static_cast<PixelFormat>(hfrStream.format),
3602 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3603 0,
3604 StreamRotation::ROTATION_0};
3605 ::android::hardware::hidl_vec<V3_2::Stream> streams = {stream};
3606 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3607 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3608 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3609 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3610 &config3_2, &config3_4, &config3_5);
3611 if (session3_5 != nullptr) {
3612 verifyStreamCombination(cameraDevice3_5, config3_4,
3613 /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3614 config3_5.streamConfigCounter = streamConfigCounter++;
3615 ret = session3_5->configureStreams_3_5(config3_5,
3616 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3617 ASSERT_EQ(Status::OK, s);
3618 ASSERT_EQ(1u, halConfig.streams.size());
3619 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
3620 });
3621 } else if (session3_4 != nullptr) {
3622 ret = session3_4->configureStreams_3_4(config3_4,
3623 [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3624 ASSERT_EQ(Status::OK, s);
3625 ASSERT_EQ(1u, halConfig.streams.size());
3626 ASSERT_EQ(halConfig.streams[0].v3_3.v3_2.id, streamId);
3627 });
3628 } else if (session3_3 != nullptr) {
3629 ret = session3_3->configureStreams_3_3(config3_2,
3630 [streamId](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3631 ASSERT_EQ(Status::OK, s);
3632 ASSERT_EQ(1u, halConfig.streams.size());
3633 ASSERT_EQ(halConfig.streams[0].v3_2.id, streamId);
3634 });
3635 } else {
3636 ret = session->configureStreams(config3_2,
3637 [streamId](Status s, HalStreamConfiguration halConfig) {
3638 ASSERT_EQ(Status::OK, s);
3639 ASSERT_EQ(1u, halConfig.streams.size());
3640 ASSERT_EQ(halConfig.streams[0].id, streamId);
3641 });
3642 }
3643 ASSERT_TRUE(ret.isOk());
3644
3645 stream = {streamId++,
3646 StreamType::OUTPUT,
3647 static_cast<uint32_t>(0),
3648 static_cast<uint32_t>(0),
3649 static_cast<PixelFormat>(hfrStream.format),
3650 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3651 0,
3652 StreamRotation::ROTATION_0};
3653 streams[0] = stream;
3654 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3655 &config3_2, &config3_4, &config3_5);
3656 if (session3_5 != nullptr) {
3657 config3_5.streamConfigCounter = streamConfigCounter++;
3658 ret = session3_5->configureStreams_3_5(config3_5,
3659 [](Status s, device::V3_4::HalStreamConfiguration) {
3660 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3661 (Status::INTERNAL_ERROR == s));
3662 });
3663 } else if (session3_4 != nullptr) {
3664 ret = session3_4->configureStreams_3_4(config3_4,
3665 [](Status s, device::V3_4::HalStreamConfiguration) {
3666 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3667 (Status::INTERNAL_ERROR == s));
3668 });
3669 } else if (session3_3 != nullptr) {
3670 ret = session3_3->configureStreams_3_3(config3_2,
3671 [](Status s, device::V3_3::HalStreamConfiguration) {
3672 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3673 (Status::INTERNAL_ERROR == s));
3674 });
3675 } else {
3676 ret = session->configureStreams(config3_2,
3677 [](Status s, HalStreamConfiguration) {
3678 ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) ||
3679 (Status::INTERNAL_ERROR == s));
3680 });
3681 }
3682 ASSERT_TRUE(ret.isOk());
3683
3684 stream = {streamId++,
3685 StreamType::OUTPUT,
3686 static_cast<uint32_t>(UINT32_MAX),
3687 static_cast<uint32_t>(UINT32_MAX),
3688 static_cast<PixelFormat>(hfrStream.format),
3689 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3690 0,
3691 StreamRotation::ROTATION_0};
3692 streams[0] = stream;
3693 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3694 &config3_2, &config3_4, &config3_5);
3695 if (session3_5 != nullptr) {
3696 config3_5.streamConfigCounter = streamConfigCounter++;
3697 ret = session3_5->configureStreams_3_5(config3_5,
3698 [](Status s, device::V3_4::HalStreamConfiguration) {
3699 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3700 });
3701 } else if (session3_4 != nullptr) {
3702 ret = session3_4->configureStreams_3_4(config3_4,
3703 [](Status s, device::V3_4::HalStreamConfiguration) {
3704 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3705 });
3706 } else if (session3_3 != nullptr) {
3707 ret = session3_3->configureStreams_3_3(config3_2,
3708 [](Status s, device::V3_3::HalStreamConfiguration) {
3709 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3710 });
3711 } else {
3712 ret = session->configureStreams(config3_2,
3713 [](Status s, HalStreamConfiguration) {
3714 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3715 });
3716 }
3717 ASSERT_TRUE(ret.isOk());
3718
3719 stream = {streamId++,
3720 StreamType::OUTPUT,
3721 static_cast<uint32_t>(hfrStream.width),
3722 static_cast<uint32_t>(hfrStream.height),
3723 static_cast<PixelFormat>(UINT32_MAX),
3724 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3725 0,
3726 StreamRotation::ROTATION_0};
3727 streams[0] = stream;
3728 createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
3729 &config3_2, &config3_4, &config3_5);
3730 if (session3_5 != nullptr) {
3731 config3_5.streamConfigCounter = streamConfigCounter++;
3732 ret = session3_5->configureStreams_3_5(config3_5,
3733 [](Status s, device::V3_4::HalStreamConfiguration) {
3734 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3735 });
3736 } else if (session3_4 != nullptr) {
3737 ret = session3_4->configureStreams_3_4(config3_4,
3738 [](Status s, device::V3_4::HalStreamConfiguration) {
3739 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3740 });
3741 } else if (session3_3 != nullptr) {
3742 ret = session3_3->configureStreams_3_3(config3_2,
3743 [](Status s, device::V3_3::HalStreamConfiguration) {
3744 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3745 });
3746 } else {
3747 ret = session->configureStreams(config3_2,
3748 [](Status s, HalStreamConfiguration) {
3749 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s);
3750 });
3751 }
3752 ASSERT_TRUE(ret.isOk());
3753
3754 free_camera_metadata(staticMeta);
3755 ret = session->close();
3756 ASSERT_TRUE(ret.isOk());
3757 }
3758 }
3759
3760 // Verify that all supported video + snapshot stream combinations can
3761 // be configured successfully.
TEST_F(CameraHidlTest,configureStreamsVideoStillOutputs)3762 TEST_F(CameraHidlTest, configureStreamsVideoStillOutputs) {
3763 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3764 std::vector<AvailableStream> outputBlobStreams;
3765 std::vector<AvailableStream> outputVideoStreams;
3766 AvailableStream videoThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3767 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3768 AvailableStream blobThreshold = {kMaxVideoWidth, kMaxVideoHeight,
3769 static_cast<int32_t>(PixelFormat::BLOB)};
3770
3771 for (const auto& name : cameraDeviceNames) {
3772 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3773 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3774 continue;
3775 } else if (deviceVersion <= 0) {
3776 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3777 ADD_FAILURE();
3778 return;
3779 }
3780
3781 camera_metadata_t* staticMeta;
3782 Return<void> ret;
3783 sp<ICameraDeviceSession> session;
3784 sp<device::V3_3::ICameraDeviceSession> session3_3;
3785 sp<device::V3_4::ICameraDeviceSession> session3_4;
3786 sp<device::V3_5::ICameraDeviceSession> session3_5;
3787 sp<device::V3_2::ICameraDevice> cameraDevice;
3788 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
3789 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
3790 &cameraDevice /*out*/);
3791 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
3792 castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
3793
3794 // Check if camera support depth only
3795 if (isDepthOnly(staticMeta)) {
3796 free_camera_metadata(staticMeta);
3797 ret = session->close();
3798 ASSERT_TRUE(ret.isOk());
3799 continue;
3800 }
3801
3802 outputBlobStreams.clear();
3803 ASSERT_EQ(Status::OK,
3804 getAvailableOutputStreams(staticMeta, outputBlobStreams,
3805 &blobThreshold));
3806 ASSERT_NE(0u, outputBlobStreams.size());
3807
3808 outputVideoStreams.clear();
3809 ASSERT_EQ(Status::OK,
3810 getAvailableOutputStreams(staticMeta, outputVideoStreams,
3811 &videoThreshold));
3812 ASSERT_NE(0u, outputVideoStreams.size());
3813
3814 uint32_t jpegBufferSize = 0;
3815 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
3816 ASSERT_NE(0u, jpegBufferSize);
3817
3818 int32_t streamId = 0;
3819 uint32_t streamConfigCounter = 0;
3820 for (auto& blobIter : outputBlobStreams) {
3821 for (auto& videoIter : outputVideoStreams) {
3822 V3_2::Stream videoStream = {streamId++,
3823 StreamType::OUTPUT,
3824 static_cast<uint32_t>(videoIter.width),
3825 static_cast<uint32_t>(videoIter.height),
3826 static_cast<PixelFormat>(videoIter.format),
3827 GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
3828 0,
3829 StreamRotation::ROTATION_0};
3830 V3_2::Stream blobStream = {streamId++,
3831 StreamType::OUTPUT,
3832 static_cast<uint32_t>(blobIter.width),
3833 static_cast<uint32_t>(blobIter.height),
3834 static_cast<PixelFormat>(blobIter.format),
3835 GRALLOC1_CONSUMER_USAGE_CPU_READ,
3836 static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF),
3837 StreamRotation::ROTATION_0};
3838 ::android::hardware::hidl_vec<V3_2::Stream> streams = {videoStream, blobStream};
3839 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
3840 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
3841 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
3842 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
3843 &config3_2, &config3_4, &config3_5, jpegBufferSize);
3844 if (session3_5 != nullptr) {
3845 verifyStreamCombination(cameraDevice3_5, config3_4,
3846 /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
3847 config3_5.streamConfigCounter = streamConfigCounter++;
3848 ret = session3_5->configureStreams_3_5(config3_5,
3849 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3850 ASSERT_EQ(Status::OK, s);
3851 ASSERT_EQ(2u, halConfig.streams.size());
3852 });
3853 } else if (session3_4 != nullptr) {
3854 ret = session3_4->configureStreams_3_4(config3_4,
3855 [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
3856 ASSERT_EQ(Status::OK, s);
3857 ASSERT_EQ(2u, halConfig.streams.size());
3858 });
3859 } else if (session3_3 != nullptr) {
3860 ret = session3_3->configureStreams_3_3(config3_2,
3861 [](Status s, device::V3_3::HalStreamConfiguration halConfig) {
3862 ASSERT_EQ(Status::OK, s);
3863 ASSERT_EQ(2u, halConfig.streams.size());
3864 });
3865 } else {
3866 ret = session->configureStreams(config3_2,
3867 [](Status s, HalStreamConfiguration halConfig) {
3868 ASSERT_EQ(Status::OK, s);
3869 ASSERT_EQ(2u, halConfig.streams.size());
3870 });
3871 }
3872 ASSERT_TRUE(ret.isOk());
3873 }
3874 }
3875
3876 free_camera_metadata(staticMeta);
3877 ret = session->close();
3878 ASSERT_TRUE(ret.isOk());
3879 }
3880 }
3881
3882 // Generate and verify a camera capture request
TEST_F(CameraHidlTest,processCaptureRequestPreview)3883 TEST_F(CameraHidlTest, processCaptureRequestPreview) {
3884 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
3885 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
3886 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
3887 uint64_t bufferId = 1;
3888 uint32_t frameNumber = 1;
3889 ::android::hardware::hidl_vec<uint8_t> settings;
3890
3891 for (const auto& name : cameraDeviceNames) {
3892 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
3893 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
3894 continue;
3895 } else if (deviceVersion <= 0) {
3896 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
3897 ADD_FAILURE();
3898 return;
3899 }
3900
3901 V3_2::Stream previewStream;
3902 HalStreamConfiguration halStreamConfig;
3903 sp<ICameraDeviceSession> session;
3904 sp<DeviceCb> cb;
3905 bool supportsPartialResults = false;
3906 bool useHalBufManager = false;
3907 uint32_t partialResultCount = 0;
3908 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
3909 &previewStream /*out*/, &halStreamConfig /*out*/,
3910 &supportsPartialResults /*out*/,
3911 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
3912
3913 std::shared_ptr<ResultMetadataQueue> resultQueue;
3914 auto resultQueueRet =
3915 session->getCaptureResultMetadataQueue(
3916 [&resultQueue](const auto& descriptor) {
3917 resultQueue = std::make_shared<ResultMetadataQueue>(
3918 descriptor);
3919 if (!resultQueue->isValid() ||
3920 resultQueue->availableToWrite() <= 0) {
3921 ALOGE("%s: HAL returns empty result metadata fmq,"
3922 " not use it", __func__);
3923 resultQueue = nullptr;
3924 // Don't use the queue onwards.
3925 }
3926 });
3927 ASSERT_TRUE(resultQueueRet.isOk());
3928
3929 InFlightRequest inflightReq = {1, false, supportsPartialResults,
3930 partialResultCount, resultQueue};
3931
3932 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
3933 Return<void> ret;
3934 ret = session->constructDefaultRequestSettings(reqTemplate,
3935 [&](auto status, const auto& req) {
3936 ASSERT_EQ(Status::OK, status);
3937 settings = req;
3938 });
3939 ASSERT_TRUE(ret.isOk());
3940
3941 hidl_handle buffer_handle;
3942 StreamBuffer outputBuffer;
3943 if (useHalBufManager) {
3944 outputBuffer = {halStreamConfig.streams[0].id,
3945 /*bufferId*/ 0,
3946 buffer_handle,
3947 BufferStatus::OK,
3948 nullptr,
3949 nullptr};
3950 } else {
3951 allocateGraphicBuffer(previewStream.width, previewStream.height,
3952 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
3953 halStreamConfig.streams[0].consumerUsage),
3954 halStreamConfig.streams[0].overrideFormat, &buffer_handle);
3955 outputBuffer = {halStreamConfig.streams[0].id,
3956 bufferId,
3957 buffer_handle,
3958 BufferStatus::OK,
3959 nullptr,
3960 nullptr};
3961 }
3962 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
3963 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
3964 nullptr};
3965 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
3966 emptyInputBuffer, outputBuffers};
3967
3968 {
3969 std::unique_lock<std::mutex> l(mLock);
3970 mInflightMap.clear();
3971 mInflightMap.add(frameNumber, &inflightReq);
3972 }
3973
3974 Status status = Status::INTERNAL_ERROR;
3975 uint32_t numRequestProcessed = 0;
3976 hidl_vec<BufferCache> cachesToRemove;
3977 Return<void> returnStatus = session->processCaptureRequest(
3978 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
3979 uint32_t n) {
3980 status = s;
3981 numRequestProcessed = n;
3982 });
3983 ASSERT_TRUE(returnStatus.isOk());
3984 ASSERT_EQ(Status::OK, status);
3985 ASSERT_EQ(numRequestProcessed, 1u);
3986
3987 {
3988 std::unique_lock<std::mutex> l(mLock);
3989 while (!inflightReq.errorCodeValid &&
3990 ((0 < inflightReq.numBuffersLeft) ||
3991 (!inflightReq.haveResultMetadata))) {
3992 auto timeout = std::chrono::system_clock::now() +
3993 std::chrono::seconds(kStreamBufferTimeoutSec);
3994 ASSERT_NE(std::cv_status::timeout,
3995 mResultCondition.wait_until(l, timeout));
3996 }
3997
3998 ASSERT_FALSE(inflightReq.errorCodeValid);
3999 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4000 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4001
4002 request.frameNumber++;
4003 // Empty settings should be supported after the first call
4004 // for repeating requests.
4005 request.settings.setToExternal(nullptr, 0, true);
4006 // The buffer has been registered to HAL by bufferId, so per
4007 // API contract we should send a null handle for this buffer
4008 request.outputBuffers[0].buffer = nullptr;
4009 mInflightMap.clear();
4010 inflightReq = {1, false, supportsPartialResults, partialResultCount,
4011 resultQueue};
4012 mInflightMap.add(request.frameNumber, &inflightReq);
4013 }
4014
4015 returnStatus = session->processCaptureRequest(
4016 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4017 uint32_t n) {
4018 status = s;
4019 numRequestProcessed = n;
4020 });
4021 ASSERT_TRUE(returnStatus.isOk());
4022 ASSERT_EQ(Status::OK, status);
4023 ASSERT_EQ(numRequestProcessed, 1u);
4024
4025 {
4026 std::unique_lock<std::mutex> l(mLock);
4027 while (!inflightReq.errorCodeValid &&
4028 ((0 < inflightReq.numBuffersLeft) ||
4029 (!inflightReq.haveResultMetadata))) {
4030 auto timeout = std::chrono::system_clock::now() +
4031 std::chrono::seconds(kStreamBufferTimeoutSec);
4032 ASSERT_NE(std::cv_status::timeout,
4033 mResultCondition.wait_until(l, timeout));
4034 }
4035
4036 ASSERT_FALSE(inflightReq.errorCodeValid);
4037 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4038 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4039 }
4040
4041 if (useHalBufManager) {
4042 verifyBuffersReturned(session, deviceVersion, previewStream.id, cb);
4043 }
4044
4045 ret = session->close();
4046 ASSERT_TRUE(ret.isOk());
4047 }
4048 }
4049
4050 // Generate and verify a multi-camera capture request
TEST_F(CameraHidlTest,processMultiCaptureRequestPreview)4051 TEST_F(CameraHidlTest, processMultiCaptureRequestPreview) {
4052 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4053 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4054 static_cast<int32_t>(PixelFormat::YCBCR_420_888)};
4055 uint64_t bufferId = 1;
4056 uint32_t frameNumber = 1;
4057 ::android::hardware::hidl_vec<uint8_t> settings;
4058 ::android::hardware::hidl_vec<uint8_t> emptySettings;
4059 hidl_string invalidPhysicalId = "-1";
4060
4061 for (const auto& name : cameraDeviceNames) {
4062 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4063 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
4064 continue;
4065 }
4066 std::string version, deviceId;
4067 ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId));
4068 camera_metadata_t* staticMeta;
4069 Return<void> ret;
4070 sp<ICameraDeviceSession> session;
4071 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/);
4072
4073 Status rc = isLogicalMultiCamera(staticMeta);
4074 if (Status::METHOD_NOT_SUPPORTED == rc) {
4075 free_camera_metadata(staticMeta);
4076 ret = session->close();
4077 ASSERT_TRUE(ret.isOk());
4078 continue;
4079 }
4080 std::unordered_set<std::string> physicalIds;
4081 rc = getPhysicalCameraIds(staticMeta, &physicalIds);
4082 ASSERT_TRUE(Status::OK == rc);
4083 ASSERT_TRUE(physicalIds.size() > 1);
4084
4085 std::unordered_set<int32_t> physicalRequestKeyIDs;
4086 rc = getSupportedKeys(staticMeta,
4087 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
4088 ASSERT_TRUE(Status::OK == rc);
4089 if (physicalRequestKeyIDs.empty()) {
4090 free_camera_metadata(staticMeta);
4091 ret = session->close();
4092 ASSERT_TRUE(ret.isOk());
4093 // The logical camera doesn't support any individual physical requests.
4094 continue;
4095 }
4096
4097 android::hardware::camera::common::V1_0::helper::CameraMetadata defaultPreviewSettings;
4098 android::hardware::camera::common::V1_0::helper::CameraMetadata filteredSettings;
4099 constructFilteredSettings(session, physicalRequestKeyIDs, RequestTemplate::PREVIEW,
4100 &defaultPreviewSettings, &filteredSettings);
4101 if (filteredSettings.isEmpty()) {
4102 // No physical device settings in default request.
4103 free_camera_metadata(staticMeta);
4104 ret = session->close();
4105 ASSERT_TRUE(ret.isOk());
4106 continue;
4107 }
4108
4109 const camera_metadata_t *settingsBuffer = defaultPreviewSettings.getAndLock();
4110 settings.setToExternal(
4111 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (settingsBuffer)),
4112 get_camera_metadata_size(settingsBuffer));
4113
4114 free_camera_metadata(staticMeta);
4115 ret = session->close();
4116 ASSERT_TRUE(ret.isOk());
4117
4118 // Leave only 2 physical devices in the id set.
4119 auto it = physicalIds.begin();
4120 string physicalDeviceId = *it; it++;
4121 physicalIds.erase(++it, physicalIds.end());
4122 ASSERT_EQ(physicalIds.size(), 2u);
4123
4124 V3_4::HalStreamConfiguration halStreamConfig;
4125 bool supportsPartialResults = false;
4126 bool useHalBufManager = false;
4127 uint32_t partialResultCount = 0;
4128 V3_2::Stream previewStream;
4129 sp<device::V3_4::ICameraDeviceSession> session3_4;
4130 sp<device::V3_5::ICameraDeviceSession> session3_5;
4131 sp<DeviceCb> cb;
4132 configurePreviewStreams3_4(name, deviceVersion, mProvider, &previewThreshold, physicalIds,
4133 &session3_4, &session3_5, &previewStream, &halStreamConfig /*out*/,
4134 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
4135 &useHalBufManager /*out*/, &cb /*out*/, 0 /*streamConfigCounter*/,
4136 true /*allowUnsupport*/);
4137 if (session3_5 == nullptr) {
4138 ret = session3_4->close();
4139 ASSERT_TRUE(ret.isOk());
4140 continue;
4141 }
4142
4143 std::shared_ptr<ResultMetadataQueue> resultQueue;
4144 auto resultQueueRet =
4145 session3_4->getCaptureResultMetadataQueue(
4146 [&resultQueue](const auto& descriptor) {
4147 resultQueue = std::make_shared<ResultMetadataQueue>(
4148 descriptor);
4149 if (!resultQueue->isValid() ||
4150 resultQueue->availableToWrite() <= 0) {
4151 ALOGE("%s: HAL returns empty result metadata fmq,"
4152 " not use it", __func__);
4153 resultQueue = nullptr;
4154 // Don't use the queue onwards.
4155 }
4156 });
4157 ASSERT_TRUE(resultQueueRet.isOk());
4158
4159 InFlightRequest inflightReq = {static_cast<ssize_t> (halStreamConfig.streams.size()), false,
4160 supportsPartialResults, partialResultCount, resultQueue};
4161
4162 std::vector<hidl_handle> graphicBuffers;
4163 graphicBuffers.reserve(halStreamConfig.streams.size());
4164 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers;
4165 outputBuffers.resize(halStreamConfig.streams.size());
4166 size_t k = 0;
4167 for (const auto& halStream : halStreamConfig.streams) {
4168 hidl_handle buffer_handle;
4169 if (useHalBufManager) {
4170 outputBuffers[k] = {halStream.v3_3.v3_2.id, /*bufferId*/0, buffer_handle,
4171 BufferStatus::OK, nullptr, nullptr};
4172 } else {
4173 allocateGraphicBuffer(previewStream.width, previewStream.height,
4174 android_convertGralloc1To0Usage(halStream.v3_3.v3_2.producerUsage,
4175 halStream.v3_3.v3_2.consumerUsage),
4176 halStream.v3_3.v3_2.overrideFormat, &buffer_handle);
4177 graphicBuffers.push_back(buffer_handle);
4178 outputBuffers[k] = {halStream.v3_3.v3_2.id, bufferId, buffer_handle,
4179 BufferStatus::OK, nullptr, nullptr};
4180 bufferId++;
4181 }
4182 k++;
4183 }
4184 hidl_vec<V3_4::PhysicalCameraSetting> camSettings(1);
4185 const camera_metadata_t *filteredSettingsBuffer = filteredSettings.getAndLock();
4186 camSettings[0].settings.setToExternal(
4187 reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (
4188 filteredSettingsBuffer)),
4189 get_camera_metadata_size(filteredSettingsBuffer));
4190 camSettings[0].fmqSettingsSize = 0;
4191 camSettings[0].physicalCameraId = physicalDeviceId;
4192
4193 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
4194 V3_4::CaptureRequest request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
4195 emptyInputBuffer, outputBuffers}, camSettings};
4196
4197 {
4198 std::unique_lock<std::mutex> l(mLock);
4199 mInflightMap.clear();
4200 mInflightMap.add(frameNumber, &inflightReq);
4201 }
4202
4203 Status stat = Status::INTERNAL_ERROR;
4204 uint32_t numRequestProcessed = 0;
4205 hidl_vec<BufferCache> cachesToRemove;
4206 Return<void> returnStatus = session3_4->processCaptureRequest_3_4(
4207 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
4208 stat = s;
4209 numRequestProcessed = n;
4210 });
4211 ASSERT_TRUE(returnStatus.isOk());
4212 ASSERT_EQ(Status::OK, stat);
4213 ASSERT_EQ(numRequestProcessed, 1u);
4214
4215 {
4216 std::unique_lock<std::mutex> l(mLock);
4217 while (!inflightReq.errorCodeValid &&
4218 ((0 < inflightReq.numBuffersLeft) ||
4219 (!inflightReq.haveResultMetadata))) {
4220 auto timeout = std::chrono::system_clock::now() +
4221 std::chrono::seconds(kStreamBufferTimeoutSec);
4222 ASSERT_NE(std::cv_status::timeout,
4223 mResultCondition.wait_until(l, timeout));
4224 }
4225
4226 ASSERT_FALSE(inflightReq.errorCodeValid);
4227 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4228
4229 request.v3_2.frameNumber++;
4230 // Empty settings should be supported after the first call
4231 // for repeating requests.
4232 request.v3_2.settings.setToExternal(nullptr, 0, true);
4233 request.physicalCameraSettings[0].settings.setToExternal(nullptr, 0, true);
4234 // The buffer has been registered to HAL by bufferId, so per
4235 // API contract we should send a null handle for this buffer
4236 request.v3_2.outputBuffers[0].buffer = nullptr;
4237 mInflightMap.clear();
4238 inflightReq = {static_cast<ssize_t> (physicalIds.size()), false,
4239 supportsPartialResults, partialResultCount, resultQueue};
4240 mInflightMap.add(request.v3_2.frameNumber, &inflightReq);
4241 }
4242
4243 returnStatus = session3_4->processCaptureRequest_3_4(
4244 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
4245 stat = s;
4246 numRequestProcessed = n;
4247 });
4248 ASSERT_TRUE(returnStatus.isOk());
4249 ASSERT_EQ(Status::OK, stat);
4250 ASSERT_EQ(numRequestProcessed, 1u);
4251
4252 {
4253 std::unique_lock<std::mutex> l(mLock);
4254 while (!inflightReq.errorCodeValid &&
4255 ((0 < inflightReq.numBuffersLeft) ||
4256 (!inflightReq.haveResultMetadata))) {
4257 auto timeout = std::chrono::system_clock::now() +
4258 std::chrono::seconds(kStreamBufferTimeoutSec);
4259 ASSERT_NE(std::cv_status::timeout,
4260 mResultCondition.wait_until(l, timeout));
4261 }
4262
4263 ASSERT_FALSE(inflightReq.errorCodeValid);
4264 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4265 }
4266
4267 // Invalid physical camera id should fail process requests
4268 frameNumber++;
4269 camSettings[0].physicalCameraId = invalidPhysicalId;
4270 camSettings[0].settings = settings;
4271 request = {{frameNumber, 0 /* fmqSettingsSize */, settings,
4272 emptyInputBuffer, outputBuffers}, camSettings};
4273 returnStatus = session3_4->processCaptureRequest_3_4(
4274 {request}, cachesToRemove, [&stat, &numRequestProcessed](auto s, uint32_t n) {
4275 stat = s;
4276 numRequestProcessed = n;
4277 });
4278 ASSERT_TRUE(returnStatus.isOk());
4279 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, stat);
4280
4281 defaultPreviewSettings.unlock(settingsBuffer);
4282 filteredSettings.unlock(filteredSettingsBuffer);
4283
4284 if (useHalBufManager) {
4285 hidl_vec<int32_t> streamIds(halStreamConfig.streams.size());
4286 for (size_t i = 0; i < streamIds.size(); i++) {
4287 streamIds[i] = halStreamConfig.streams[i].v3_3.v3_2.id;
4288 }
4289 verifyBuffersReturned(session3_4, streamIds, cb);
4290 }
4291
4292 ret = session3_4->close();
4293 ASSERT_TRUE(ret.isOk());
4294 }
4295 }
4296
4297 // Generate and verify a burst containing alternating sensor sensitivity values
TEST_F(CameraHidlTest,processCaptureRequestBurstISO)4298 TEST_F(CameraHidlTest, processCaptureRequestBurstISO) {
4299 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4300 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4301 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4302 uint64_t bufferId = 1;
4303 uint32_t frameNumber = 1;
4304 float isoTol = .03f;
4305 ::android::hardware::hidl_vec<uint8_t> settings;
4306
4307 for (const auto& name : cameraDeviceNames) {
4308 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4309 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4310 continue;
4311 } else if (deviceVersion <= 0) {
4312 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4313 ADD_FAILURE();
4314 return;
4315 }
4316 camera_metadata_t* staticMetaBuffer;
4317 Return<void> ret;
4318 sp<ICameraDeviceSession> session;
4319 openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
4320 ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
4321 staticMetaBuffer);
4322
4323 camera_metadata_entry_t hwLevel = staticMeta.find(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
4324 ASSERT_TRUE(0 < hwLevel.count);
4325 if (ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED == hwLevel.data.u8[0] ||
4326 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL == hwLevel.data.u8[0]) {
4327 //Limited/External devices can skip this test
4328 ret = session->close();
4329 ASSERT_TRUE(ret.isOk());
4330 continue;
4331 }
4332
4333 camera_metadata_entry_t isoRange = staticMeta.find(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
4334 ASSERT_EQ(isoRange.count, 2u);
4335
4336 ret = session->close();
4337 ASSERT_TRUE(ret.isOk());
4338
4339 bool supportsPartialResults = false;
4340 bool useHalBufManager = false;
4341 uint32_t partialResultCount = 0;
4342 V3_2::Stream previewStream;
4343 HalStreamConfiguration halStreamConfig;
4344 sp<DeviceCb> cb;
4345 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold,
4346 &session /*out*/, &previewStream /*out*/, &halStreamConfig /*out*/,
4347 &supportsPartialResults /*out*/, &partialResultCount /*out*/,
4348 &useHalBufManager /*out*/, &cb /*out*/);
4349 std::shared_ptr<ResultMetadataQueue> resultQueue;
4350
4351 auto resultQueueRet = session->getCaptureResultMetadataQueue(
4352 [&resultQueue](const auto& descriptor) {
4353 resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
4354 if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
4355 ALOGE("%s: HAL returns empty result metadata fmq,"
4356 " not use it", __func__);
4357 resultQueue = nullptr;
4358 // Don't use the queue onwards.
4359 }
4360 });
4361 ASSERT_TRUE(resultQueueRet.isOk());
4362 ASSERT_NE(nullptr, resultQueue);
4363
4364 ret = session->constructDefaultRequestSettings(RequestTemplate::PREVIEW,
4365 [&](auto status, const auto& req) {
4366 ASSERT_EQ(Status::OK, status);
4367 settings = req; });
4368 ASSERT_TRUE(ret.isOk());
4369
4370 ::android::hardware::camera::common::V1_0::helper::CameraMetadata requestMeta;
4371 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
4372 hidl_handle buffers[kBurstFrameCount];
4373 StreamBuffer outputBuffers[kBurstFrameCount];
4374 CaptureRequest requests[kBurstFrameCount];
4375 InFlightRequest inflightReqs[kBurstFrameCount];
4376 int32_t isoValues[kBurstFrameCount];
4377 hidl_vec<uint8_t> requestSettings[kBurstFrameCount];
4378 for (uint32_t i = 0; i < kBurstFrameCount; i++) {
4379 std::unique_lock<std::mutex> l(mLock);
4380
4381 isoValues[i] = ((i % 2) == 0) ? isoRange.data.i32[0] : isoRange.data.i32[1];
4382 if (useHalBufManager) {
4383 outputBuffers[i] = {halStreamConfig.streams[0].id, /*bufferId*/0,
4384 nullptr, BufferStatus::OK, nullptr, nullptr};
4385 } else {
4386 allocateGraphicBuffer(previewStream.width, previewStream.height,
4387 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
4388 halStreamConfig.streams[0].consumerUsage),
4389 halStreamConfig.streams[0].overrideFormat, &buffers[i]);
4390 outputBuffers[i] = {halStreamConfig.streams[0].id, bufferId + i,
4391 buffers[i], BufferStatus::OK, nullptr, nullptr};
4392 }
4393
4394 requestMeta.append(reinterpret_cast<camera_metadata_t *> (settings.data()));
4395
4396 // Disable all 3A routines
4397 uint8_t mode = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
4398 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_CONTROL_MODE, &mode, 1));
4399 ASSERT_EQ(::android::OK, requestMeta.update(ANDROID_SENSOR_SENSITIVITY, &isoValues[i],
4400 1));
4401 camera_metadata_t *metaBuffer = requestMeta.release();
4402 requestSettings[i].setToExternal(reinterpret_cast<uint8_t *> (metaBuffer),
4403 get_camera_metadata_size(metaBuffer), true);
4404
4405 requests[i] = {frameNumber + i, 0 /* fmqSettingsSize */, requestSettings[i],
4406 emptyInputBuffer, {outputBuffers[i]}};
4407
4408 inflightReqs[i] = {1, false, supportsPartialResults, partialResultCount, resultQueue};
4409 mInflightMap.add(frameNumber + i, &inflightReqs[i]);
4410 }
4411
4412 Status status = Status::INTERNAL_ERROR;
4413 uint32_t numRequestProcessed = 0;
4414 hidl_vec<BufferCache> cachesToRemove;
4415 hidl_vec<CaptureRequest> burstRequest;
4416 burstRequest.setToExternal(requests, kBurstFrameCount);
4417 Return<void> returnStatus = session->processCaptureRequest(burstRequest, cachesToRemove,
4418 [&status, &numRequestProcessed] (auto s, uint32_t n) {
4419 status = s;
4420 numRequestProcessed = n;
4421 });
4422 ASSERT_TRUE(returnStatus.isOk());
4423 ASSERT_EQ(Status::OK, status);
4424 ASSERT_EQ(numRequestProcessed, kBurstFrameCount);
4425
4426 for (size_t i = 0; i < kBurstFrameCount; i++) {
4427 std::unique_lock<std::mutex> l(mLock);
4428 while (!inflightReqs[i].errorCodeValid && ((0 < inflightReqs[i].numBuffersLeft) ||
4429 (!inflightReqs[i].haveResultMetadata))) {
4430 auto timeout = std::chrono::system_clock::now() +
4431 std::chrono::seconds(kStreamBufferTimeoutSec);
4432 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
4433 }
4434
4435 ASSERT_FALSE(inflightReqs[i].errorCodeValid);
4436 ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
4437 ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
4438 ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
4439 ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
4440 camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
4441 ANDROID_SENSOR_SENSITIVITY);
4442 ASSERT_TRUE(std::abs(isoResult.data.i32[0] - isoValues[i]) <=
4443 std::round(isoValues[i]*isoTol));
4444 }
4445
4446 if (useHalBufManager) {
4447 verifyBuffersReturned(session, deviceVersion, previewStream.id, cb);
4448 }
4449 ret = session->close();
4450 ASSERT_TRUE(ret.isOk());
4451 }
4452 }
4453
4454 // Test whether an incorrect capture request with missing settings will
4455 // be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidSinglePreview)4456 TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
4457 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4458 std::vector<AvailableStream> outputPreviewStreams;
4459 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4460 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4461 uint64_t bufferId = 1;
4462 uint32_t frameNumber = 1;
4463 ::android::hardware::hidl_vec<uint8_t> settings;
4464
4465 for (const auto& name : cameraDeviceNames) {
4466 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4467 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4468 continue;
4469 } else if (deviceVersion <= 0) {
4470 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4471 ADD_FAILURE();
4472 return;
4473 }
4474
4475 V3_2::Stream previewStream;
4476 HalStreamConfiguration halStreamConfig;
4477 sp<ICameraDeviceSession> session;
4478 sp<DeviceCb> cb;
4479 bool supportsPartialResults = false;
4480 bool useHalBufManager = false;
4481 uint32_t partialResultCount = 0;
4482 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4483 &previewStream /*out*/, &halStreamConfig /*out*/,
4484 &supportsPartialResults /*out*/,
4485 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4486
4487 hidl_handle buffer_handle;
4488
4489 if (useHalBufManager) {
4490 bufferId = 0;
4491 } else {
4492 allocateGraphicBuffer(previewStream.width, previewStream.height,
4493 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
4494 halStreamConfig.streams[0].consumerUsage),
4495 halStreamConfig.streams[0].overrideFormat, &buffer_handle);
4496 }
4497
4498 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
4499 bufferId,
4500 buffer_handle,
4501 BufferStatus::OK,
4502 nullptr,
4503 nullptr};
4504 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
4505 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
4506 nullptr};
4507 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
4508 emptyInputBuffer, outputBuffers};
4509
4510 // Settings were not correctly initialized, we should fail here
4511 Status status = Status::OK;
4512 uint32_t numRequestProcessed = 0;
4513 hidl_vec<BufferCache> cachesToRemove;
4514 Return<void> ret = session->processCaptureRequest(
4515 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4516 uint32_t n) {
4517 status = s;
4518 numRequestProcessed = n;
4519 });
4520 ASSERT_TRUE(ret.isOk());
4521 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
4522 ASSERT_EQ(numRequestProcessed, 0u);
4523
4524 ret = session->close();
4525 ASSERT_TRUE(ret.isOk());
4526 }
4527 }
4528
4529 // Check whether an invalid capture request with missing output buffers
4530 // will be reported correctly.
TEST_F(CameraHidlTest,processCaptureRequestInvalidBuffer)4531 TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
4532 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4533 std::vector<AvailableStream> outputBlobStreams;
4534 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4535 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4536 uint32_t frameNumber = 1;
4537 ::android::hardware::hidl_vec<uint8_t> settings;
4538
4539 for (const auto& name : cameraDeviceNames) {
4540 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4541 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4542 continue;
4543 } else if (deviceVersion <= 0) {
4544 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4545 ADD_FAILURE();
4546 return;
4547 }
4548
4549 V3_2::Stream previewStream;
4550 HalStreamConfiguration halStreamConfig;
4551 sp<ICameraDeviceSession> session;
4552 sp<DeviceCb> cb;
4553 bool supportsPartialResults = false;
4554 bool useHalBufManager = false;
4555 uint32_t partialResultCount = 0;
4556 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4557 &previewStream /*out*/, &halStreamConfig /*out*/,
4558 &supportsPartialResults /*out*/,
4559 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4560
4561 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
4562 Return<void> ret;
4563 ret = session->constructDefaultRequestSettings(reqTemplate,
4564 [&](auto status, const auto& req) {
4565 ASSERT_EQ(Status::OK, status);
4566 settings = req;
4567 });
4568 ASSERT_TRUE(ret.isOk());
4569
4570 ::android::hardware::hidl_vec<StreamBuffer> emptyOutputBuffers;
4571 StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr,
4572 nullptr};
4573 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
4574 emptyInputBuffer, emptyOutputBuffers};
4575
4576 // Output buffers are missing, we should fail here
4577 Status status = Status::OK;
4578 uint32_t numRequestProcessed = 0;
4579 hidl_vec<BufferCache> cachesToRemove;
4580 ret = session->processCaptureRequest(
4581 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4582 uint32_t n) {
4583 status = s;
4584 numRequestProcessed = n;
4585 });
4586 ASSERT_TRUE(ret.isOk());
4587 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
4588 ASSERT_EQ(numRequestProcessed, 0u);
4589
4590 ret = session->close();
4591 ASSERT_TRUE(ret.isOk());
4592 }
4593 }
4594
4595 // Generate, trigger and flush a preview request
TEST_F(CameraHidlTest,flushPreviewRequest)4596 TEST_F(CameraHidlTest, flushPreviewRequest) {
4597 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4598 std::vector<AvailableStream> outputPreviewStreams;
4599 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4600 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4601 uint64_t bufferId = 1;
4602 uint32_t frameNumber = 1;
4603 ::android::hardware::hidl_vec<uint8_t> settings;
4604
4605 for (const auto& name : cameraDeviceNames) {
4606 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4607 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4608 continue;
4609 } else if (deviceVersion <= 0) {
4610 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4611 ADD_FAILURE();
4612 return;
4613 }
4614
4615 V3_2::Stream previewStream;
4616 HalStreamConfiguration halStreamConfig;
4617 sp<ICameraDeviceSession> session;
4618 sp<DeviceCb> cb;
4619 bool supportsPartialResults = false;
4620 bool useHalBufManager = false;
4621 uint32_t partialResultCount = 0;
4622 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4623 &previewStream /*out*/, &halStreamConfig /*out*/,
4624 &supportsPartialResults /*out*/,
4625 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4626
4627 std::shared_ptr<ResultMetadataQueue> resultQueue;
4628 auto resultQueueRet =
4629 session->getCaptureResultMetadataQueue(
4630 [&resultQueue](const auto& descriptor) {
4631 resultQueue = std::make_shared<ResultMetadataQueue>(
4632 descriptor);
4633 if (!resultQueue->isValid() ||
4634 resultQueue->availableToWrite() <= 0) {
4635 ALOGE("%s: HAL returns empty result metadata fmq,"
4636 " not use it", __func__);
4637 resultQueue = nullptr;
4638 // Don't use the queue onwards.
4639 }
4640 });
4641 ASSERT_TRUE(resultQueueRet.isOk());
4642
4643 InFlightRequest inflightReq = {1, false, supportsPartialResults,
4644 partialResultCount, resultQueue};
4645 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
4646 Return<void> ret;
4647 ret = session->constructDefaultRequestSettings(reqTemplate,
4648 [&](auto status, const auto& req) {
4649 ASSERT_EQ(Status::OK, status);
4650 settings = req;
4651 });
4652 ASSERT_TRUE(ret.isOk());
4653
4654 hidl_handle buffer_handle;
4655 if (useHalBufManager) {
4656 bufferId = 0;
4657 } else {
4658 allocateGraphicBuffer(previewStream.width, previewStream.height,
4659 android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
4660 halStreamConfig.streams[0].consumerUsage),
4661 halStreamConfig.streams[0].overrideFormat, &buffer_handle);
4662 }
4663
4664 StreamBuffer outputBuffer = {halStreamConfig.streams[0].id,
4665 bufferId,
4666 buffer_handle,
4667 BufferStatus::OK,
4668 nullptr,
4669 nullptr};
4670 ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
4671 const StreamBuffer emptyInputBuffer = {-1, 0, nullptr,
4672 BufferStatus::ERROR, nullptr, nullptr};
4673 CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings,
4674 emptyInputBuffer, outputBuffers};
4675
4676 {
4677 std::unique_lock<std::mutex> l(mLock);
4678 mInflightMap.clear();
4679 mInflightMap.add(frameNumber, &inflightReq);
4680 }
4681
4682 Status status = Status::INTERNAL_ERROR;
4683 uint32_t numRequestProcessed = 0;
4684 hidl_vec<BufferCache> cachesToRemove;
4685 ret = session->processCaptureRequest(
4686 {request}, cachesToRemove, [&status, &numRequestProcessed](auto s,
4687 uint32_t n) {
4688 status = s;
4689 numRequestProcessed = n;
4690 });
4691
4692 ASSERT_TRUE(ret.isOk());
4693 ASSERT_EQ(Status::OK, status);
4694 ASSERT_EQ(numRequestProcessed, 1u);
4695 // Flush before waiting for request to complete.
4696 Return<Status> returnStatus = session->flush();
4697 ASSERT_TRUE(returnStatus.isOk());
4698 ASSERT_EQ(Status::OK, returnStatus);
4699
4700 {
4701 std::unique_lock<std::mutex> l(mLock);
4702 while (!inflightReq.errorCodeValid &&
4703 ((0 < inflightReq.numBuffersLeft) ||
4704 (!inflightReq.haveResultMetadata))) {
4705 auto timeout = std::chrono::system_clock::now() +
4706 std::chrono::seconds(kStreamBufferTimeoutSec);
4707 ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l,
4708 timeout));
4709 }
4710
4711 if (!inflightReq.errorCodeValid) {
4712 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
4713 ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
4714 } else {
4715 switch (inflightReq.errorCode) {
4716 case ErrorCode::ERROR_REQUEST:
4717 case ErrorCode::ERROR_RESULT:
4718 case ErrorCode::ERROR_BUFFER:
4719 // Expected
4720 break;
4721 case ErrorCode::ERROR_DEVICE:
4722 default:
4723 FAIL() << "Unexpected error:"
4724 << static_cast<uint32_t>(inflightReq.errorCode);
4725 }
4726 }
4727 }
4728
4729 if (useHalBufManager) {
4730 verifyBuffersReturned(session, deviceVersion, previewStream.id, cb);
4731 }
4732
4733 ret = session->close();
4734 ASSERT_TRUE(ret.isOk());
4735 }
4736 }
4737
4738 // Verify that camera flushes correctly without any pending requests.
TEST_F(CameraHidlTest,flushEmpty)4739 TEST_F(CameraHidlTest, flushEmpty) {
4740 hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
4741 std::vector<AvailableStream> outputPreviewStreams;
4742 AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4743 static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
4744
4745 for (const auto& name : cameraDeviceNames) {
4746 int deviceVersion = getCameraDeviceVersion(name, mProviderType);
4747 if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
4748 continue;
4749 } else if (deviceVersion <= 0) {
4750 ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
4751 ADD_FAILURE();
4752 return;
4753 }
4754
4755 V3_2::Stream previewStream;
4756 HalStreamConfiguration halStreamConfig;
4757 sp<ICameraDeviceSession> session;
4758 sp<DeviceCb> cb;
4759 bool supportsPartialResults = false;
4760 bool useHalBufManager = false;
4761 uint32_t partialResultCount = 0;
4762 configurePreviewStream(name, deviceVersion, mProvider, &previewThreshold, &session /*out*/,
4763 &previewStream /*out*/, &halStreamConfig /*out*/,
4764 &supportsPartialResults /*out*/,
4765 &partialResultCount /*out*/, &useHalBufManager /*out*/, &cb /*out*/);
4766
4767 Return<Status> returnStatus = session->flush();
4768 ASSERT_TRUE(returnStatus.isOk());
4769 ASSERT_EQ(Status::OK, returnStatus);
4770
4771 {
4772 std::unique_lock<std::mutex> l(mLock);
4773 auto timeout = std::chrono::system_clock::now() +
4774 std::chrono::milliseconds(kEmptyFlushTimeoutMSec);
4775 ASSERT_EQ(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
4776 }
4777
4778 Return<void> ret = session->close();
4779 ASSERT_TRUE(ret.isOk());
4780 }
4781 }
4782
4783 // Test camera provider@2.5 notify method
TEST_F(CameraHidlTest,providerDeviceStateNotification)4784 TEST_F(CameraHidlTest, providerDeviceStateNotification) {
4785
4786 notifyDeviceState(provider::V2_5::DeviceState::BACK_COVERED);
4787 notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
4788 }
4789
4790 // Retrieve all valid output stream resolutions from the camera
4791 // static characteristics.
getAvailableOutputStreams(camera_metadata_t * staticMeta,std::vector<AvailableStream> & outputStreams,const AvailableStream * threshold)4792 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
4793 std::vector<AvailableStream> &outputStreams,
4794 const AvailableStream *threshold) {
4795 AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
4796 static_cast<int32_t>(PixelFormat::Y16)};
4797 if (nullptr == staticMeta) {
4798 return Status::ILLEGAL_ARGUMENT;
4799 }
4800
4801 camera_metadata_ro_entry scalarEntry;
4802 camera_metadata_ro_entry depthEntry;
4803 int foundScalar = find_camera_metadata_ro_entry(staticMeta,
4804 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry);
4805 int foundDepth = find_camera_metadata_ro_entry(staticMeta,
4806 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
4807 if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) &&
4808 (0 != foundDepth || (0 != (depthEntry.count % 4)))) {
4809 return Status::ILLEGAL_ARGUMENT;
4810 }
4811
4812 if(foundScalar == 0 && (0 == (scalarEntry.count % 4))) {
4813 fillOutputStreams(&scalarEntry, outputStreams, threshold,
4814 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT);
4815 }
4816
4817 if(foundDepth == 0 && (0 == (depthEntry.count % 4))) {
4818 fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
4819 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
4820 }
4821
4822 return Status::OK;
4823 }
4824
fillOutputStreams(camera_metadata_ro_entry_t * entry,std::vector<AvailableStream> & outputStreams,const AvailableStream * threshold,const int32_t availableConfigOutputTag)4825 void CameraHidlTest::fillOutputStreams(camera_metadata_ro_entry_t* entry,
4826 std::vector<AvailableStream>& outputStreams, const AvailableStream* threshold,
4827 const int32_t availableConfigOutputTag) {
4828 for (size_t i = 0; i < entry->count; i+=4) {
4829 if (availableConfigOutputTag == entry->data.i32[i + 3]) {
4830 if(nullptr == threshold) {
4831 AvailableStream s = {entry->data.i32[i+1],
4832 entry->data.i32[i+2], entry->data.i32[i]};
4833 outputStreams.push_back(s);
4834 } else {
4835 if ((threshold->format == entry->data.i32[i]) &&
4836 (threshold->width >= entry->data.i32[i+1]) &&
4837 (threshold->height >= entry->data.i32[i+2])) {
4838 AvailableStream s = {entry->data.i32[i+1],
4839 entry->data.i32[i+2], threshold->format};
4840 outputStreams.push_back(s);
4841 }
4842 }
4843 }
4844 }
4845 }
4846
4847 // Get max jpeg buffer size in android.jpeg.maxSize
getJpegBufferSize(camera_metadata_t * staticMeta,uint32_t * outBufSize)4848 Status CameraHidlTest::getJpegBufferSize(camera_metadata_t *staticMeta, uint32_t* outBufSize) {
4849 if (nullptr == staticMeta || nullptr == outBufSize) {
4850 return Status::ILLEGAL_ARGUMENT;
4851 }
4852
4853 camera_metadata_ro_entry entry;
4854 int rc = find_camera_metadata_ro_entry(staticMeta,
4855 ANDROID_JPEG_MAX_SIZE, &entry);
4856 if ((0 != rc) || (1 != entry.count)) {
4857 return Status::ILLEGAL_ARGUMENT;
4858 }
4859
4860 *outBufSize = static_cast<uint32_t>(entry.data.i32[0]);
4861 return Status::OK;
4862 }
4863
4864 // Check if the camera device has logical multi-camera capability.
isLogicalMultiCamera(const camera_metadata_t * staticMeta)4865 Status CameraHidlTest::isLogicalMultiCamera(const camera_metadata_t *staticMeta) {
4866 Status ret = Status::METHOD_NOT_SUPPORTED;
4867 if (nullptr == staticMeta) {
4868 return Status::ILLEGAL_ARGUMENT;
4869 }
4870
4871 camera_metadata_ro_entry entry;
4872 int rc = find_camera_metadata_ro_entry(staticMeta,
4873 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4874 if (0 != rc) {
4875 return Status::ILLEGAL_ARGUMENT;
4876 }
4877
4878 for (size_t i = 0; i < entry.count; i++) {
4879 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA == entry.data.u8[i]) {
4880 ret = Status::OK;
4881 break;
4882 }
4883 }
4884
4885 return ret;
4886 }
4887
4888 // Generate a list of physical camera ids backing a logical multi-camera.
getPhysicalCameraIds(const camera_metadata_t * staticMeta,std::unordered_set<std::string> * physicalIds)4889 Status CameraHidlTest::getPhysicalCameraIds(const camera_metadata_t *staticMeta,
4890 std::unordered_set<std::string> *physicalIds) {
4891 if ((nullptr == staticMeta) || (nullptr == physicalIds)) {
4892 return Status::ILLEGAL_ARGUMENT;
4893 }
4894
4895 camera_metadata_ro_entry entry;
4896 int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS,
4897 &entry);
4898 if (0 != rc) {
4899 return Status::ILLEGAL_ARGUMENT;
4900 }
4901
4902 const uint8_t* ids = entry.data.u8;
4903 size_t start = 0;
4904 for (size_t i = 0; i < entry.count; i++) {
4905 if (ids[i] == '\0') {
4906 if (start != i) {
4907 std::string currentId(reinterpret_cast<const char *> (ids + start));
4908 physicalIds->emplace(currentId);
4909 }
4910 start = i + 1;
4911 }
4912 }
4913
4914 return Status::OK;
4915 }
4916
4917 // Generate a set of suported camera key ids.
getSupportedKeys(camera_metadata_t * staticMeta,uint32_t tagId,std::unordered_set<int32_t> * requestIDs)4918 Status CameraHidlTest::getSupportedKeys(camera_metadata_t *staticMeta,
4919 uint32_t tagId, std::unordered_set<int32_t> *requestIDs) {
4920 if ((nullptr == staticMeta) || (nullptr == requestIDs)) {
4921 return Status::ILLEGAL_ARGUMENT;
4922 }
4923
4924 camera_metadata_ro_entry entry;
4925 int rc = find_camera_metadata_ro_entry(staticMeta, tagId, &entry);
4926 if ((0 != rc) || (entry.count == 0)) {
4927 return Status::OK;
4928 }
4929
4930 requestIDs->insert(entry.data.i32, entry.data.i32 + entry.count);
4931
4932 return Status::OK;
4933 }
4934
constructFilteredSettings(const sp<ICameraDeviceSession> & session,const std::unordered_set<int32_t> & availableKeys,RequestTemplate reqTemplate,android::hardware::camera::common::V1_0::helper::CameraMetadata * defaultSettings,android::hardware::camera::common::V1_0::helper::CameraMetadata * filteredSettings)4935 void CameraHidlTest::constructFilteredSettings(const sp<ICameraDeviceSession>& session,
4936 const std::unordered_set<int32_t>& availableKeys, RequestTemplate reqTemplate,
4937 android::hardware::camera::common::V1_0::helper::CameraMetadata* defaultSettings,
4938 android::hardware::camera::common::V1_0::helper::CameraMetadata* filteredSettings) {
4939 ASSERT_NE(defaultSettings, nullptr);
4940 ASSERT_NE(filteredSettings, nullptr);
4941
4942 auto ret = session->constructDefaultRequestSettings(reqTemplate,
4943 [&defaultSettings] (auto status, const auto& req) mutable {
4944 ASSERT_EQ(Status::OK, status);
4945
4946 const camera_metadata_t *metadata = reinterpret_cast<const camera_metadata_t*> (
4947 req.data());
4948 size_t expectedSize = req.size();
4949 int result = validate_camera_metadata_structure(metadata, &expectedSize);
4950 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
4951
4952 size_t entryCount = get_camera_metadata_entry_count(metadata);
4953 ASSERT_GT(entryCount, 0u);
4954 *defaultSettings = metadata;
4955 });
4956 ASSERT_TRUE(ret.isOk());
4957 const android::hardware::camera::common::V1_0::helper::CameraMetadata &constSettings =
4958 *defaultSettings;
4959 for (const auto& keyIt : availableKeys) {
4960 camera_metadata_ro_entry entry = constSettings.find(keyIt);
4961 if (entry.count > 0) {
4962 filteredSettings->update(entry);
4963 }
4964 }
4965 }
4966
4967 // Check if constrained mode is supported by using the static
4968 // camera characteristics.
isConstrainedModeAvailable(camera_metadata_t * staticMeta)4969 Status CameraHidlTest::isConstrainedModeAvailable(camera_metadata_t *staticMeta) {
4970 Status ret = Status::METHOD_NOT_SUPPORTED;
4971 if (nullptr == staticMeta) {
4972 return Status::ILLEGAL_ARGUMENT;
4973 }
4974
4975 camera_metadata_ro_entry entry;
4976 int rc = find_camera_metadata_ro_entry(staticMeta,
4977 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
4978 if (0 != rc) {
4979 return Status::ILLEGAL_ARGUMENT;
4980 }
4981
4982 for (size_t i = 0; i < entry.count; i++) {
4983 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ==
4984 entry.data.u8[i]) {
4985 ret = Status::OK;
4986 break;
4987 }
4988 }
4989
4990 return ret;
4991 }
4992
4993 // Pick the largest supported HFR mode from the static camera
4994 // characteristics.
pickConstrainedModeSize(camera_metadata_t * staticMeta,AvailableStream & hfrStream)4995 Status CameraHidlTest::pickConstrainedModeSize(camera_metadata_t *staticMeta,
4996 AvailableStream &hfrStream) {
4997 if (nullptr == staticMeta) {
4998 return Status::ILLEGAL_ARGUMENT;
4999 }
5000
5001 camera_metadata_ro_entry entry;
5002 int rc = find_camera_metadata_ro_entry(staticMeta,
5003 ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS, &entry);
5004 if (0 != rc) {
5005 return Status::METHOD_NOT_SUPPORTED;
5006 } else if (0 != (entry.count % 5)) {
5007 return Status::ILLEGAL_ARGUMENT;
5008 }
5009
5010 hfrStream = {0, 0,
5011 static_cast<uint32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
5012 for (size_t i = 0; i < entry.count; i+=5) {
5013 int32_t w = entry.data.i32[i];
5014 int32_t h = entry.data.i32[i+1];
5015 if ((hfrStream.width * hfrStream.height) < (w *h)) {
5016 hfrStream.width = w;
5017 hfrStream.height = h;
5018 }
5019 }
5020
5021 return Status::OK;
5022 }
5023
5024 // Check whether ZSL is available using the static camera
5025 // characteristics.
isZSLModeAvailable(const camera_metadata_t * staticMeta)5026 Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta) {
5027 if (Status::OK == isZSLModeAvailable(staticMeta, PRIV_REPROCESS)) {
5028 return Status::OK;
5029 } else {
5030 return isZSLModeAvailable(staticMeta, YUV_REPROCESS);
5031 }
5032 }
5033
isZSLModeAvailable(const camera_metadata_t * staticMeta,ReprocessType reprocType)5034 Status CameraHidlTest::isZSLModeAvailable(const camera_metadata_t *staticMeta,
5035 ReprocessType reprocType) {
5036
5037 Status ret = Status::METHOD_NOT_SUPPORTED;
5038 if (nullptr == staticMeta) {
5039 return Status::ILLEGAL_ARGUMENT;
5040 }
5041
5042 camera_metadata_ro_entry entry;
5043 int rc = find_camera_metadata_ro_entry(staticMeta,
5044 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
5045 if (0 != rc) {
5046 return Status::ILLEGAL_ARGUMENT;
5047 }
5048
5049 for (size_t i = 0; i < entry.count; i++) {
5050 if ((reprocType == PRIV_REPROCESS &&
5051 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING == entry.data.u8[i]) ||
5052 (reprocType == YUV_REPROCESS &&
5053 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING == entry.data.u8[i])) {
5054 ret = Status::OK;
5055 break;
5056 }
5057 }
5058
5059 return ret;
5060 }
5061
5062 // Check whether this is a monochrome camera using the static camera characteristics.
isMonochromeCamera(const camera_metadata_t * staticMeta)5063 Status CameraHidlTest::isMonochromeCamera(const camera_metadata_t *staticMeta) {
5064 Status ret = Status::METHOD_NOT_SUPPORTED;
5065 if (nullptr == staticMeta) {
5066 return Status::ILLEGAL_ARGUMENT;
5067 }
5068
5069 camera_metadata_ro_entry entry;
5070 int rc = find_camera_metadata_ro_entry(staticMeta,
5071 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
5072 if (0 != rc) {
5073 return Status::ILLEGAL_ARGUMENT;
5074 }
5075
5076 for (size_t i = 0; i < entry.count; i++) {
5077 if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME == entry.data.u8[i]) {
5078 ret = Status::OK;
5079 break;
5080 }
5081 }
5082
5083 return ret;
5084 }
5085
5086 // Retrieve the reprocess input-output format map from the static
5087 // camera characteristics.
getZSLInputOutputMap(camera_metadata_t * staticMeta,std::vector<AvailableZSLInputOutput> & inputOutputMap)5088 Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta,
5089 std::vector<AvailableZSLInputOutput> &inputOutputMap) {
5090 if (nullptr == staticMeta) {
5091 return Status::ILLEGAL_ARGUMENT;
5092 }
5093
5094 camera_metadata_ro_entry entry;
5095 int rc = find_camera_metadata_ro_entry(staticMeta,
5096 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP, &entry);
5097 if ((0 != rc) || (0 >= entry.count)) {
5098 return Status::ILLEGAL_ARGUMENT;
5099 }
5100
5101 const int32_t* contents = &entry.data.i32[0];
5102 for (size_t i = 0; i < entry.count; ) {
5103 int32_t inputFormat = contents[i++];
5104 int32_t length = contents[i++];
5105 for (int32_t j = 0; j < length; j++) {
5106 int32_t outputFormat = contents[i+j];
5107 AvailableZSLInputOutput zslEntry = {inputFormat, outputFormat};
5108 inputOutputMap.push_back(zslEntry);
5109 }
5110 i += length;
5111 }
5112
5113 return Status::OK;
5114 }
5115
5116 // Search for the largest stream size for a given format.
findLargestSize(const std::vector<AvailableStream> & streamSizes,int32_t format,AvailableStream & result)5117 Status CameraHidlTest::findLargestSize(
5118 const std::vector<AvailableStream> &streamSizes, int32_t format,
5119 AvailableStream &result) {
5120 result = {0, 0, 0};
5121 for (auto &iter : streamSizes) {
5122 if (format == iter.format) {
5123 if ((result.width * result.height) < (iter.width * iter.height)) {
5124 result = iter;
5125 }
5126 }
5127 }
5128
5129 return (result.format == format) ? Status::OK : Status::ILLEGAL_ARGUMENT;
5130 }
5131
5132 // Check whether the camera device supports specific focus mode.
isAutoFocusModeAvailable(CameraParameters & cameraParams,const char * mode)5133 Status CameraHidlTest::isAutoFocusModeAvailable(
5134 CameraParameters &cameraParams,
5135 const char *mode) {
5136 ::android::String8 focusModes(cameraParams.get(
5137 CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
5138 if (focusModes.contains(mode)) {
5139 return Status::OK;
5140 }
5141
5142 return Status::METHOD_NOT_SUPPORTED;
5143 }
5144
createStreamConfiguration(const::android::hardware::hidl_vec<V3_2::Stream> & streams3_2,StreamConfigurationMode configMode,::android::hardware::camera::device::V3_2::StreamConfiguration * config3_2,::android::hardware::camera::device::V3_4::StreamConfiguration * config3_4,::android::hardware::camera::device::V3_5::StreamConfiguration * config3_5,uint32_t jpegBufferSize)5145 void CameraHidlTest::createStreamConfiguration(
5146 const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
5147 StreamConfigurationMode configMode,
5148 ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/,
5149 ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/,
5150 ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5 /*out*/,
5151 uint32_t jpegBufferSize) {
5152 ASSERT_NE(nullptr, config3_2);
5153 ASSERT_NE(nullptr, config3_4);
5154 ASSERT_NE(nullptr, config3_5);
5155
5156 ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(streams3_2.size());
5157 size_t idx = 0;
5158 for (auto& stream3_2 : streams3_2) {
5159 V3_4::Stream stream;
5160 stream.v3_2 = stream3_2;
5161 stream.bufferSize = 0;
5162 if (stream3_2.format == PixelFormat::BLOB &&
5163 stream3_2.dataSpace == static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF)) {
5164 stream.bufferSize = jpegBufferSize;
5165 }
5166 streams3_4[idx++] = stream;
5167 }
5168 // Caller is responsible to fill in non-zero config3_5->streamConfigCounter after this returns
5169 *config3_5 = {{streams3_4, configMode, {}}, 0};
5170 *config3_4 = config3_5->v3_4;
5171 *config3_2 = {streams3_2, configMode};
5172 }
5173
5174 // Configure multiple preview streams using different physical ids.
configurePreviewStreams3_4(const std::string & name,int32_t deviceVersion,sp<ICameraProvider> provider,const AvailableStream * previewThreshold,const std::unordered_set<std::string> & physicalIds,sp<device::V3_4::ICameraDeviceSession> * session3_4,sp<device::V3_5::ICameraDeviceSession> * session3_5,V3_2::Stream * previewStream,device::V3_4::HalStreamConfiguration * halStreamConfig,bool * supportsPartialResults,uint32_t * partialResultCount,bool * useHalBufManager,sp<DeviceCb> * outCb,uint32_t streamConfigCounter,bool allowUnsupport)5175 void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
5176 sp<ICameraProvider> provider,
5177 const AvailableStream *previewThreshold,
5178 const std::unordered_set<std::string>& physicalIds,
5179 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
5180 sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
5181 V3_2::Stream *previewStream /*out*/,
5182 device::V3_4::HalStreamConfiguration *halStreamConfig /*out*/,
5183 bool *supportsPartialResults /*out*/,
5184 uint32_t *partialResultCount /*out*/,
5185 bool *useHalBufManager /*out*/,
5186 sp<DeviceCb> *outCb /*out*/,
5187 uint32_t streamConfigCounter,
5188 bool allowUnsupport) {
5189 ASSERT_NE(nullptr, session3_4);
5190 ASSERT_NE(nullptr, session3_5);
5191 ASSERT_NE(nullptr, halStreamConfig);
5192 ASSERT_NE(nullptr, previewStream);
5193 ASSERT_NE(nullptr, supportsPartialResults);
5194 ASSERT_NE(nullptr, partialResultCount);
5195 ASSERT_NE(nullptr, useHalBufManager);
5196 ASSERT_NE(nullptr, outCb);
5197 ASSERT_FALSE(physicalIds.empty());
5198
5199 std::vector<AvailableStream> outputPreviewStreams;
5200 ::android::sp<ICameraDevice> device3_x;
5201 ALOGI("configureStreams: Testing camera device %s", name.c_str());
5202 Return<void> ret;
5203 ret = provider->getCameraDeviceInterface_V3_x(
5204 name,
5205 [&](auto status, const auto& device) {
5206 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
5207 (int)status);
5208 ASSERT_EQ(Status::OK, status);
5209 ASSERT_NE(device, nullptr);
5210 device3_x = device;
5211 });
5212 ASSERT_TRUE(ret.isOk());
5213
5214 camera_metadata_t *staticMeta;
5215 ret = device3_x->getCameraCharacteristics([&] (Status s,
5216 CameraMetadata metadata) {
5217 ASSERT_EQ(Status::OK, s);
5218 staticMeta = clone_camera_metadata(
5219 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
5220 ASSERT_NE(nullptr, staticMeta);
5221 });
5222 ASSERT_TRUE(ret.isOk());
5223
5224 camera_metadata_ro_entry entry;
5225 auto status = find_camera_metadata_ro_entry(staticMeta,
5226 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
5227 if ((0 == status) && (entry.count > 0)) {
5228 *partialResultCount = entry.data.i32[0];
5229 *supportsPartialResults = (*partialResultCount > 1);
5230 }
5231
5232 sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
5233 sp<ICameraDeviceSession> session;
5234 ret = device3_x->open(
5235 cb,
5236 [&session](auto status, const auto& newSession) {
5237 ALOGI("device::open returns status:%d", (int)status);
5238 ASSERT_EQ(Status::OK, status);
5239 ASSERT_NE(newSession, nullptr);
5240 session = newSession;
5241 });
5242 ASSERT_TRUE(ret.isOk());
5243 *outCb = cb;
5244
5245 sp<device::V3_3::ICameraDeviceSession> session3_3;
5246 castSession(session, deviceVersion, &session3_3, session3_4, session3_5);
5247 ASSERT_NE(nullptr, (*session3_4).get());
5248
5249 *useHalBufManager = false;
5250 status = find_camera_metadata_ro_entry(staticMeta,
5251 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
5252 if ((0 == status) && (entry.count == 1)) {
5253 *useHalBufManager = (entry.data.u8[0] ==
5254 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
5255 }
5256
5257 outputPreviewStreams.clear();
5258 auto rc = getAvailableOutputStreams(staticMeta,
5259 outputPreviewStreams, previewThreshold);
5260 free_camera_metadata(staticMeta);
5261 ASSERT_EQ(Status::OK, rc);
5262 ASSERT_FALSE(outputPreviewStreams.empty());
5263
5264 ::android::hardware::hidl_vec<V3_4::Stream> streams3_4(physicalIds.size());
5265 int32_t streamId = 0;
5266 for (auto const& physicalId : physicalIds) {
5267 V3_4::Stream stream3_4 = {{streamId, StreamType::OUTPUT,
5268 static_cast<uint32_t> (outputPreviewStreams[0].width),
5269 static_cast<uint32_t> (outputPreviewStreams[0].height),
5270 static_cast<PixelFormat> (outputPreviewStreams[0].format),
5271 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, 0, StreamRotation::ROTATION_0},
5272 physicalId.c_str(), /*bufferSize*/ 0};
5273 streams3_4[streamId++] = stream3_4;
5274 }
5275
5276 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
5277 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
5278 config3_4 = {streams3_4, StreamConfigurationMode::NORMAL_MODE, {}};
5279 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
5280 ret = (*session3_4)->constructDefaultRequestSettings(reqTemplate,
5281 [&config3_4](auto status, const auto& req) {
5282 ASSERT_EQ(Status::OK, status);
5283 config3_4.sessionParams = req;
5284 });
5285 ASSERT_TRUE(ret.isOk());
5286
5287 ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5);
5288 if (allowUnsupport) {
5289 sp<device::V3_5::ICameraDevice> cameraDevice3_5;
5290 castDevice(device3_x, deviceVersion, &cameraDevice3_5);
5291
5292 bool supported = false;
5293 ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
5294 [&supported](Status s, bool combStatus) {
5295 ASSERT_TRUE((Status::OK == s) ||
5296 (Status::METHOD_NOT_SUPPORTED == s));
5297 if (Status::OK == s) {
5298 supported = combStatus;
5299 }
5300 });
5301 ASSERT_TRUE(ret.isOk());
5302 // If stream combination is not supported, return null session.
5303 if (!supported) {
5304 *session3_5 = nullptr;
5305 return;
5306 }
5307 }
5308
5309 if (*session3_5 != nullptr) {
5310 config3_5.v3_4 = config3_4;
5311 config3_5.streamConfigCounter = streamConfigCounter;
5312 ret = (*session3_5)->configureStreams_3_5(config3_5,
5313 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5314 ASSERT_EQ(Status::OK, s);
5315 ASSERT_EQ(physicalIds.size(), halConfig.streams.size());
5316 *halStreamConfig = halConfig;
5317 if (*useHalBufManager) {
5318 hidl_vec<V3_2::Stream> streams(physicalIds.size());
5319 hidl_vec<V3_2::HalStream> halStreams(physicalIds.size());
5320 for (size_t i = 0; i < physicalIds.size(); i++) {
5321 streams[i] = streams3_4[i].v3_2;
5322 halStreams[i] = halConfig.streams[i].v3_3.v3_2;
5323 }
5324 cb->setCurrentStreamConfig(streams, halStreams);
5325 }
5326 });
5327 } else {
5328 ret = (*session3_4)->configureStreams_3_4(config3_4,
5329 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5330 ASSERT_EQ(Status::OK, s);
5331 ASSERT_EQ(physicalIds.size(), halConfig.streams.size());
5332 *halStreamConfig = halConfig;
5333 });
5334 }
5335 *previewStream = streams3_4[0].v3_2;
5336 ASSERT_TRUE(ret.isOk());
5337 }
5338
isDepthOnly(camera_metadata_t * staticMeta)5339 bool CameraHidlTest::isDepthOnly(camera_metadata_t* staticMeta) {
5340 camera_metadata_ro_entry scalarEntry;
5341 camera_metadata_ro_entry depthEntry;
5342
5343 int rc = find_camera_metadata_ro_entry(
5344 staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &scalarEntry);
5345 if (rc == 0) {
5346 for (uint32_t i = 0; i < scalarEntry.count; i++) {
5347 if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
5348 return false;
5349 }
5350 }
5351 }
5352
5353 for (uint32_t i = 0; i < scalarEntry.count; i++) {
5354 if (scalarEntry.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) {
5355
5356 rc = find_camera_metadata_ro_entry(
5357 staticMeta, ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry);
5358 size_t i = 0;
5359 if (rc == 0 && depthEntry.data.i32[i] == static_cast<int32_t>(PixelFormat::Y16)) {
5360 // only Depth16 format is supported now
5361 return true;
5362 }
5363 break;
5364 }
5365 }
5366
5367 return false;
5368 }
5369
5370 // Open a device session and configure a preview stream.
configurePreviewStream(const std::string & name,int32_t deviceVersion,sp<ICameraProvider> provider,const AvailableStream * previewThreshold,sp<ICameraDeviceSession> * session,V3_2::Stream * previewStream,HalStreamConfiguration * halStreamConfig,bool * supportsPartialResults,uint32_t * partialResultCount,bool * useHalBufManager,sp<DeviceCb> * outCb,uint32_t streamConfigCounter)5371 void CameraHidlTest::configurePreviewStream(const std::string &name, int32_t deviceVersion,
5372 sp<ICameraProvider> provider,
5373 const AvailableStream *previewThreshold,
5374 sp<ICameraDeviceSession> *session /*out*/,
5375 V3_2::Stream *previewStream /*out*/,
5376 HalStreamConfiguration *halStreamConfig /*out*/,
5377 bool *supportsPartialResults /*out*/,
5378 uint32_t *partialResultCount /*out*/,
5379 bool *useHalBufManager /*out*/,
5380 sp<DeviceCb> *outCb /*out*/,
5381 uint32_t streamConfigCounter) {
5382 ASSERT_NE(nullptr, session);
5383 ASSERT_NE(nullptr, previewStream);
5384 ASSERT_NE(nullptr, halStreamConfig);
5385 ASSERT_NE(nullptr, supportsPartialResults);
5386 ASSERT_NE(nullptr, partialResultCount);
5387 ASSERT_NE(nullptr, useHalBufManager);
5388 ASSERT_NE(nullptr, outCb);
5389
5390 std::vector<AvailableStream> outputPreviewStreams;
5391 ::android::sp<ICameraDevice> device3_x;
5392 ALOGI("configureStreams: Testing camera device %s", name.c_str());
5393 Return<void> ret;
5394 ret = provider->getCameraDeviceInterface_V3_x(
5395 name,
5396 [&](auto status, const auto& device) {
5397 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
5398 (int)status);
5399 ASSERT_EQ(Status::OK, status);
5400 ASSERT_NE(device, nullptr);
5401 device3_x = device;
5402 });
5403 ASSERT_TRUE(ret.isOk());
5404
5405 camera_metadata_t *staticMeta;
5406 ret = device3_x->getCameraCharacteristics([&] (Status s,
5407 CameraMetadata metadata) {
5408 ASSERT_EQ(Status::OK, s);
5409 staticMeta = clone_camera_metadata(
5410 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
5411 ASSERT_NE(nullptr, staticMeta);
5412 });
5413 ASSERT_TRUE(ret.isOk());
5414
5415 camera_metadata_ro_entry entry;
5416 auto status = find_camera_metadata_ro_entry(staticMeta,
5417 ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
5418 if ((0 == status) && (entry.count > 0)) {
5419 *partialResultCount = entry.data.i32[0];
5420 *supportsPartialResults = (*partialResultCount > 1);
5421 }
5422
5423 sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
5424 ret = device3_x->open(
5425 cb,
5426 [&](auto status, const auto& newSession) {
5427 ALOGI("device::open returns status:%d", (int)status);
5428 ASSERT_EQ(Status::OK, status);
5429 ASSERT_NE(newSession, nullptr);
5430 *session = newSession;
5431 });
5432 ASSERT_TRUE(ret.isOk());
5433 *outCb = cb;
5434
5435 sp<device::V3_3::ICameraDeviceSession> session3_3;
5436 sp<device::V3_4::ICameraDeviceSession> session3_4;
5437 sp<device::V3_5::ICameraDeviceSession> session3_5;
5438 castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5);
5439
5440 *useHalBufManager = false;
5441 status = find_camera_metadata_ro_entry(staticMeta,
5442 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
5443 if ((0 == status) && (entry.count == 1)) {
5444 *useHalBufManager = (entry.data.u8[0] ==
5445 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
5446 }
5447
5448 outputPreviewStreams.clear();
5449 auto rc = getAvailableOutputStreams(staticMeta,
5450 outputPreviewStreams, previewThreshold);
5451
5452 uint32_t jpegBufferSize = 0;
5453 ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
5454 ASSERT_NE(0u, jpegBufferSize);
5455
5456 free_camera_metadata(staticMeta);
5457 ASSERT_EQ(Status::OK, rc);
5458 ASSERT_FALSE(outputPreviewStreams.empty());
5459
5460 V3_2::DataspaceFlags dataspaceFlag = 0;
5461 switch (static_cast<PixelFormat>(outputPreviewStreams[0].format)) {
5462 case PixelFormat::Y16:
5463 dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
5464 break;
5465 default:
5466 dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
5467 }
5468
5469 V3_2::Stream stream3_2 = {0, StreamType::OUTPUT,
5470 static_cast<uint32_t> (outputPreviewStreams[0].width),
5471 static_cast<uint32_t> (outputPreviewStreams[0].height),
5472 static_cast<PixelFormat> (outputPreviewStreams[0].format),
5473 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, dataspaceFlag, StreamRotation::ROTATION_0};
5474 ::android::hardware::hidl_vec<V3_2::Stream> streams3_2 = {stream3_2};
5475 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
5476 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
5477 ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
5478 createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
5479 &config3_2, &config3_4, &config3_5, jpegBufferSize);
5480 if (session3_5 != nullptr) {
5481 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
5482 ret = session3_5->constructDefaultRequestSettings(reqTemplate,
5483 [&config3_5](auto status, const auto& req) {
5484 ASSERT_EQ(Status::OK, status);
5485 config3_5.v3_4.sessionParams = req;
5486 });
5487 ASSERT_TRUE(ret.isOk());
5488 config3_5.streamConfigCounter = streamConfigCounter;
5489 ret = session3_5->configureStreams_3_5(config3_5,
5490 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5491 ASSERT_EQ(Status::OK, s);
5492 ASSERT_EQ(1u, halConfig.streams.size());
5493 halStreamConfig->streams.resize(1);
5494 halStreamConfig->streams[0] = halConfig.streams[0].v3_3.v3_2;
5495 if (*useHalBufManager) {
5496 hidl_vec<V3_2::Stream> streams(1);
5497 hidl_vec<V3_2::HalStream> halStreams(1);
5498 streams[0] = stream3_2;
5499 halStreams[0] = halConfig.streams[0].v3_3.v3_2;
5500 cb->setCurrentStreamConfig(streams, halStreams);
5501 }
5502 });
5503 } else if (session3_4 != nullptr) {
5504 RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
5505 ret = session3_4->constructDefaultRequestSettings(reqTemplate,
5506 [&config3_4](auto status, const auto& req) {
5507 ASSERT_EQ(Status::OK, status);
5508 config3_4.sessionParams = req;
5509 });
5510 ASSERT_TRUE(ret.isOk());
5511 ret = session3_4->configureStreams_3_4(config3_4,
5512 [&] (Status s, device::V3_4::HalStreamConfiguration halConfig) {
5513 ASSERT_EQ(Status::OK, s);
5514 ASSERT_EQ(1u, halConfig.streams.size());
5515 halStreamConfig->streams.resize(halConfig.streams.size());
5516 for (size_t i = 0; i < halConfig.streams.size(); i++) {
5517 halStreamConfig->streams[i] = halConfig.streams[i].v3_3.v3_2;
5518 }
5519 });
5520 } else if (session3_3 != nullptr) {
5521 ret = session3_3->configureStreams_3_3(config3_2,
5522 [&] (Status s, device::V3_3::HalStreamConfiguration halConfig) {
5523 ASSERT_EQ(Status::OK, s);
5524 ASSERT_EQ(1u, halConfig.streams.size());
5525 halStreamConfig->streams.resize(halConfig.streams.size());
5526 for (size_t i = 0; i < halConfig.streams.size(); i++) {
5527 halStreamConfig->streams[i] = halConfig.streams[i].v3_2;
5528 }
5529 });
5530 } else {
5531 ret = (*session)->configureStreams(config3_2,
5532 [&] (Status s, HalStreamConfiguration halConfig) {
5533 ASSERT_EQ(Status::OK, s);
5534 ASSERT_EQ(1u, halConfig.streams.size());
5535 *halStreamConfig = halConfig;
5536 });
5537 }
5538 *previewStream = stream3_2;
5539 ASSERT_TRUE(ret.isOk());
5540 }
5541
castDevice(const sp<device::V3_2::ICameraDevice> & device,int32_t deviceVersion,sp<device::V3_5::ICameraDevice> * device3_5)5542 void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice> &device,
5543 int32_t deviceVersion, sp<device::V3_5::ICameraDevice> *device3_5/*out*/) {
5544 ASSERT_NE(nullptr, device3_5);
5545 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
5546 auto castResult = device::V3_5::ICameraDevice::castFrom(device);
5547 ASSERT_TRUE(castResult.isOk());
5548 *device3_5 = castResult;
5549 }
5550 }
5551
5552 //Cast camera provider to corresponding version if available
castProvider(const sp<ICameraProvider> & provider,sp<provider::V2_5::ICameraProvider> * provider2_5)5553 void CameraHidlTest::castProvider(const sp<ICameraProvider> &provider,
5554 sp<provider::V2_5::ICameraProvider> *provider2_5 /*out*/) {
5555 ASSERT_NE(nullptr, provider2_5);
5556 auto castResult = provider::V2_5::ICameraProvider::castFrom(provider);
5557 if (castResult.isOk()) {
5558 *provider2_5 = castResult;
5559 }
5560 }
5561
5562 //Cast camera device session to corresponding version
castSession(const sp<ICameraDeviceSession> & session,int32_t deviceVersion,sp<device::V3_3::ICameraDeviceSession> * session3_3,sp<device::V3_4::ICameraDeviceSession> * session3_4,sp<device::V3_5::ICameraDeviceSession> * session3_5)5563 void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
5564 sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
5565 sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
5566 sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/) {
5567 ASSERT_NE(nullptr, session3_3);
5568 ASSERT_NE(nullptr, session3_4);
5569 ASSERT_NE(nullptr, session3_5);
5570
5571 switch (deviceVersion) {
5572 case CAMERA_DEVICE_API_VERSION_3_5: {
5573 auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session);
5574 ASSERT_TRUE(castResult.isOk());
5575 *session3_5 = castResult;
5576 }
5577 [[fallthrough]];
5578 case CAMERA_DEVICE_API_VERSION_3_4: {
5579 auto castResult = device::V3_4::ICameraDeviceSession::castFrom(session);
5580 ASSERT_TRUE(castResult.isOk());
5581 *session3_4 = castResult;
5582 }
5583 [[fallthrough]];
5584 case CAMERA_DEVICE_API_VERSION_3_3: {
5585 auto castResult = device::V3_3::ICameraDeviceSession::castFrom(session);
5586 ASSERT_TRUE(castResult.isOk());
5587 *session3_3 = castResult;
5588 break;
5589 }
5590 default:
5591 //no-op
5592 return;
5593 }
5594 }
5595
verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,const::android::hardware::camera::device::V3_4::StreamConfiguration & config3_4,bool expectedStatus,bool expectMethodSupported)5596 void CameraHidlTest::verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
5597 const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
5598 bool expectedStatus, bool expectMethodSupported) {
5599 if (cameraDevice3_5.get() != nullptr) {
5600 auto ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
5601 [expectedStatus, expectMethodSupported] (Status s, bool combStatus) {
5602 ASSERT_TRUE((Status::OK == s) ||
5603 (!expectMethodSupported && Status::METHOD_NOT_SUPPORTED == s));
5604 if (Status::OK == s) {
5605 ASSERT_TRUE(combStatus == expectedStatus);
5606 }
5607 });
5608 ASSERT_TRUE(ret.isOk());
5609 }
5610 }
5611
5612 // Verify logical camera static metadata
verifyLogicalCameraMetadata(const std::string & cameraName,const::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> & device,const CameraMetadata & chars,int deviceVersion,const hidl_vec<hidl_string> & deviceNames)5613 void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName,
5614 const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device,
5615 const CameraMetadata &chars, int deviceVersion,
5616 const hidl_vec<hidl_string>& deviceNames) {
5617 const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
5618 ASSERT_NE(nullptr, metadata);
5619
5620 Status rc = isLogicalMultiCamera(metadata);
5621 ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc);
5622 if (Status::METHOD_NOT_SUPPORTED == rc) {
5623 return;
5624 }
5625
5626 std::string version, cameraId;
5627 ASSERT_TRUE(::matchDeviceName(cameraName, mProviderType, &version, &cameraId));
5628 std::unordered_set<std::string> physicalIds;
5629 ASSERT_TRUE(Status::OK == getPhysicalCameraIds(metadata, &physicalIds));
5630 for (auto physicalId : physicalIds) {
5631 ASSERT_NE(physicalId, cameraId);
5632 bool isPublicId = false;
5633 for (auto& deviceName : deviceNames) {
5634 std::string publicVersion, publicId;
5635 ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, &publicVersion, &publicId));
5636 if (physicalId == publicId) {
5637 isPublicId = true;
5638 break;
5639 }
5640 }
5641 if (isPublicId) {
5642 continue;
5643 }
5644
5645 ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
5646 auto castResult = device::V3_5::ICameraDevice::castFrom(device);
5647 ASSERT_TRUE(castResult.isOk());
5648 ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> device3_5 =
5649 castResult;
5650 ASSERT_NE(device3_5, nullptr);
5651
5652 // Check camera characteristics for hidden camera id
5653 Return<void> ret = device3_5->getPhysicalCameraCharacteristics(physicalId,
5654 [&](auto status, const auto& chars) {
5655 verifyCameraCharacteristics(status, chars);
5656 verifyMonochromeCharacteristics(chars, deviceVersion);
5657 });
5658 ASSERT_TRUE(ret.isOk());
5659
5660 // Check calling getCameraDeviceInterface_V3_x() on hidden camera id returns
5661 // ILLEGAL_ARGUMENT.
5662 std::stringstream s;
5663 s << "device@" << version << "/" << mProviderType << "/" << physicalId;
5664 hidl_string fullPhysicalId(s.str());
5665 ret = mProvider->getCameraDeviceInterface_V3_x(fullPhysicalId,
5666 [&](auto status, const auto& device3_x) {
5667 ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status);
5668 ASSERT_EQ(device3_x, nullptr);
5669 });
5670 ASSERT_TRUE(ret.isOk());
5671 }
5672
5673 // Make sure ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID is available in
5674 // result keys.
5675 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
5676 camera_metadata_ro_entry entry;
5677 int retcode = find_camera_metadata_ro_entry(metadata,
5678 ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
5679 if ((0 == retcode) && (entry.count > 0)) {
5680 ASSERT_NE(std::find(entry.data.i32, entry.data.i32 + entry.count,
5681 static_cast<int32_t>(
5682 CameraMetadataTag::ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID)),
5683 entry.data.i32 + entry.count);
5684 } else {
5685 ADD_FAILURE() << "Get camera availableResultKeys failed!";
5686 }
5687 }
5688 }
5689
verifyCameraCharacteristics(Status status,const CameraMetadata & chars)5690 void CameraHidlTest::verifyCameraCharacteristics(Status status, const CameraMetadata& chars) {
5691 ASSERT_EQ(Status::OK, status);
5692 const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
5693 size_t expectedSize = chars.size();
5694 int result = validate_camera_metadata_structure(metadata, &expectedSize);
5695 ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
5696 size_t entryCount = get_camera_metadata_entry_count(metadata);
5697 // TODO: we can do better than 0 here. Need to check how many required
5698 // characteristics keys we've defined.
5699 ASSERT_GT(entryCount, 0u);
5700
5701 camera_metadata_ro_entry entry;
5702 int retcode = find_camera_metadata_ro_entry(metadata,
5703 ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, &entry);
5704 if ((0 == retcode) && (entry.count > 0)) {
5705 uint8_t hardwareLevel = entry.data.u8[0];
5706 ASSERT_TRUE(
5707 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED ||
5708 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL ||
5709 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3 ||
5710 hardwareLevel == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL);
5711 } else {
5712 ADD_FAILURE() << "Get camera hardware level failed!";
5713 }
5714
5715 entry.count = 0;
5716 retcode = find_camera_metadata_ro_entry(metadata,
5717 ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, &entry);
5718 if ((0 == retcode) || (entry.count > 0)) {
5719 ADD_FAILURE() << "ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION "
5720 << " per API contract should never be set by Hal!";
5721 }
5722 retcode = find_camera_metadata_ro_entry(metadata,
5723 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, &entry);
5724 if ((0 == retcode) || (entry.count > 0)) {
5725 ADD_FAILURE() << "ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS"
5726 << " per API contract should never be set by Hal!";
5727 }
5728 retcode = find_camera_metadata_ro_entry(metadata,
5729 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS, &entry);
5730 if ((0 == retcode) || (entry.count > 0)) {
5731 ADD_FAILURE() << "ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS"
5732 << " per API contract should never be set by Hal!";
5733 }
5734 retcode = find_camera_metadata_ro_entry(metadata,
5735 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS, &entry);
5736 if ((0 == retcode) || (entry.count > 0)) {
5737 ADD_FAILURE() << "ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS"
5738 << " per API contract should never be set by Hal!";
5739 }
5740
5741 retcode = find_camera_metadata_ro_entry(metadata,
5742 ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, &entry);
5743 if (0 == retcode || entry.count > 0) {
5744 ADD_FAILURE() << "ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS "
5745 << " per API contract should never be set by Hal!";
5746 }
5747
5748 retcode = find_camera_metadata_ro_entry(metadata,
5749 ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS, &entry);
5750 if (0 == retcode || entry.count > 0) {
5751 ADD_FAILURE() << "ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS "
5752 << " per API contract should never be set by Hal!";
5753 }
5754
5755 retcode = find_camera_metadata_ro_entry(metadata,
5756 ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS, &entry);
5757 if (0 == retcode || entry.count > 0) {
5758 ADD_FAILURE() << "ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS "
5759 << " per API contract should never be set by Hal!";
5760 }
5761
5762 retcode = find_camera_metadata_ro_entry(metadata,
5763 ANDROID_HEIC_INFO_SUPPORTED, &entry);
5764 if (0 == retcode && entry.count > 0) {
5765 retcode = find_camera_metadata_ro_entry(metadata,
5766 ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT, &entry);
5767 if (0 == retcode && entry.count > 0) {
5768 uint8_t maxJpegAppSegmentsCount = entry.data.u8[0];
5769 ASSERT_TRUE(maxJpegAppSegmentsCount >= 1 &&
5770 maxJpegAppSegmentsCount <= 16);
5771 } else {
5772 ADD_FAILURE() << "Get Heic maxJpegAppSegmentsCount failed!";
5773 }
5774 }
5775 }
5776
verifyMonochromeCharacteristics(const CameraMetadata & chars,int deviceVersion)5777 void CameraHidlTest::verifyMonochromeCharacteristics(const CameraMetadata& chars,
5778 int deviceVersion) {
5779 const camera_metadata_t* metadata = (camera_metadata_t*)chars.data();
5780 Status rc = isMonochromeCamera(metadata);
5781 if (Status::METHOD_NOT_SUPPORTED == rc) {
5782 return;
5783 }
5784 ASSERT_EQ(Status::OK, rc);
5785
5786 camera_metadata_ro_entry entry;
5787 // Check capabilities
5788 int retcode = find_camera_metadata_ro_entry(metadata,
5789 ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry);
5790 if ((0 == retcode) && (entry.count > 0)) {
5791 ASSERT_EQ(std::find(entry.data.u8, entry.data.u8 + entry.count,
5792 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING),
5793 entry.data.u8 + entry.count);
5794 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
5795 ASSERT_EQ(std::find(entry.data.u8, entry.data.u8 + entry.count,
5796 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW),
5797 entry.data.u8 + entry.count);
5798 }
5799 }
5800
5801 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) {
5802 // Check Cfa
5803 retcode = find_camera_metadata_ro_entry(metadata,
5804 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &entry);
5805 if ((0 == retcode) && (entry.count == 1)) {
5806 ASSERT_TRUE(entry.data.i32[0] == static_cast<int32_t>(
5807 CameraMetadataEnumAndroidSensorInfoColorFilterArrangement::ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO)
5808 || entry.data.i32[0] == static_cast<int32_t>(
5809 CameraMetadataEnumAndroidSensorInfoColorFilterArrangement::ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR));
5810 }
5811
5812 // Check availableRequestKeys
5813 retcode = find_camera_metadata_ro_entry(metadata,
5814 ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, &entry);
5815 if ((0 == retcode) && (entry.count > 0)) {
5816 for (size_t i = 0; i < entry.count; i++) {
5817 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_MODE);
5818 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_TRANSFORM);
5819 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_GAINS);
5820 }
5821 } else {
5822 ADD_FAILURE() << "Get camera availableRequestKeys failed!";
5823 }
5824
5825 // Check availableResultKeys
5826 retcode = find_camera_metadata_ro_entry(metadata,
5827 ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry);
5828 if ((0 == retcode) && (entry.count > 0)) {
5829 for (size_t i = 0; i < entry.count; i++) {
5830 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_GREEN_SPLIT);
5831 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_NEUTRAL_COLOR_POINT);
5832 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_MODE);
5833 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_TRANSFORM);
5834 ASSERT_NE(entry.data.i32[i], ANDROID_COLOR_CORRECTION_GAINS);
5835 }
5836 } else {
5837 ADD_FAILURE() << "Get camera availableResultKeys failed!";
5838 }
5839
5840 // Check availableCharacteristicKeys
5841 retcode = find_camera_metadata_ro_entry(metadata,
5842 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &entry);
5843 if ((0 == retcode) && (entry.count > 0)) {
5844 for (size_t i = 0; i < entry.count; i++) {
5845 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_REFERENCE_ILLUMINANT1);
5846 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_REFERENCE_ILLUMINANT2);
5847 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_CALIBRATION_TRANSFORM1);
5848 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_CALIBRATION_TRANSFORM2);
5849 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_COLOR_TRANSFORM1);
5850 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_COLOR_TRANSFORM2);
5851 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_FORWARD_MATRIX1);
5852 ASSERT_NE(entry.data.i32[i], ANDROID_SENSOR_FORWARD_MATRIX2);
5853 }
5854 } else {
5855 ADD_FAILURE() << "Get camera availableResultKeys failed!";
5856 }
5857
5858 // Check blackLevelPattern
5859 retcode = find_camera_metadata_ro_entry(metadata,
5860 ANDROID_SENSOR_BLACK_LEVEL_PATTERN, &entry);
5861 if ((0 == retcode) && (entry.count > 0)) {
5862 ASSERT_EQ(entry.count, 4);
5863 for (size_t i = 1; i < entry.count; i++) {
5864 ASSERT_EQ(entry.data.i32[i], entry.data.i32[0]);
5865 }
5866 }
5867 }
5868 }
5869
verifyMonochromeCameraResult(const::android::hardware::camera::common::V1_0::helper::CameraMetadata & metadata)5870 void CameraHidlTest::verifyMonochromeCameraResult(
5871 const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata) {
5872 camera_metadata_ro_entry entry;
5873
5874 // Check tags that are not applicable for monochrome camera
5875 ASSERT_FALSE(metadata.exists(ANDROID_SENSOR_GREEN_SPLIT));
5876 ASSERT_FALSE(metadata.exists(ANDROID_SENSOR_NEUTRAL_COLOR_POINT));
5877 ASSERT_FALSE(metadata.exists(ANDROID_COLOR_CORRECTION_MODE));
5878 ASSERT_FALSE(metadata.exists(ANDROID_COLOR_CORRECTION_TRANSFORM));
5879 ASSERT_FALSE(metadata.exists(ANDROID_COLOR_CORRECTION_GAINS));
5880
5881 // Check dynamicBlackLevel
5882 entry = metadata.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
5883 if (entry.count > 0) {
5884 ASSERT_EQ(entry.count, 4);
5885 for (size_t i = 1; i < entry.count; i++) {
5886 ASSERT_FLOAT_EQ(entry.data.f[i], entry.data.f[0]);
5887 }
5888 }
5889
5890 // Check noiseProfile
5891 entry = metadata.find(ANDROID_SENSOR_NOISE_PROFILE);
5892 if (entry.count > 0) {
5893 ASSERT_EQ(entry.count, 2);
5894 }
5895
5896 // Check lensShadingMap
5897 entry = metadata.find(ANDROID_STATISTICS_LENS_SHADING_MAP);
5898 if (entry.count > 0) {
5899 ASSERT_EQ(entry.count % 4, 0);
5900 for (size_t i = 0; i < entry.count/4; i++) {
5901 ASSERT_FLOAT_EQ(entry.data.f[i*4+1], entry.data.f[i*4]);
5902 ASSERT_FLOAT_EQ(entry.data.f[i*4+2], entry.data.f[i*4]);
5903 ASSERT_FLOAT_EQ(entry.data.f[i*4+3], entry.data.f[i*4]);
5904 }
5905 }
5906
5907 // Check tonemapCurve
5908 camera_metadata_ro_entry curveRed = metadata.find(ANDROID_TONEMAP_CURVE_RED);
5909 camera_metadata_ro_entry curveGreen = metadata.find(ANDROID_TONEMAP_CURVE_GREEN);
5910 camera_metadata_ro_entry curveBlue = metadata.find(ANDROID_TONEMAP_CURVE_BLUE);
5911 if (curveRed.count > 0 && curveGreen.count > 0 && curveBlue.count > 0) {
5912 ASSERT_EQ(curveRed.count, curveGreen.count);
5913 ASSERT_EQ(curveRed.count, curveBlue.count);
5914 for (size_t i = 0; i < curveRed.count; i++) {
5915 ASSERT_FLOAT_EQ(curveGreen.data.f[i], curveRed.data.f[i]);
5916 ASSERT_FLOAT_EQ(curveBlue.data.f[i], curveRed.data.f[i]);
5917 }
5918 }
5919 }
5920
verifyBuffersReturned(sp<device::V3_2::ICameraDeviceSession> session,int deviceVersion,int32_t streamId,sp<DeviceCb> cb,uint32_t streamConfigCounter)5921 void CameraHidlTest::verifyBuffersReturned(
5922 sp<device::V3_2::ICameraDeviceSession> session,
5923 int deviceVersion, int32_t streamId,
5924 sp<DeviceCb> cb, uint32_t streamConfigCounter) {
5925 sp<device::V3_3::ICameraDeviceSession> session3_3;
5926 sp<device::V3_4::ICameraDeviceSession> session3_4;
5927 sp<device::V3_5::ICameraDeviceSession> session3_5;
5928 castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5);
5929 ASSERT_NE(nullptr, session3_5.get());
5930
5931 hidl_vec<int32_t> streamIds(1);
5932 streamIds[0] = streamId;
5933 session3_5->signalStreamFlush(streamIds, /*streamConfigCounter*/streamConfigCounter);
5934 cb->waitForBuffersReturned();
5935 }
5936
verifyBuffersReturned(sp<device::V3_4::ICameraDeviceSession> session3_4,hidl_vec<int32_t> streamIds,sp<DeviceCb> cb,uint32_t streamConfigCounter)5937 void CameraHidlTest::verifyBuffersReturned(
5938 sp<device::V3_4::ICameraDeviceSession> session3_4,
5939 hidl_vec<int32_t> streamIds, sp<DeviceCb> cb, uint32_t streamConfigCounter) {
5940 auto castResult = device::V3_5::ICameraDeviceSession::castFrom(session3_4);
5941 ASSERT_TRUE(castResult.isOk());
5942 sp<device::V3_5::ICameraDeviceSession> session3_5 = castResult;
5943 ASSERT_NE(nullptr, session3_5.get());
5944
5945 session3_5->signalStreamFlush(streamIds, /*streamConfigCounter*/streamConfigCounter);
5946 cb->waitForBuffersReturned();
5947 }
5948
verifyLogicalCameraResult(const camera_metadata_t * staticMetadata,const::android::hardware::camera::common::V1_0::helper::CameraMetadata & resultMetadata)5949 void CameraHidlTest::verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
5950 const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata) {
5951 std::unordered_set<std::string> physicalIds;
5952 Status rc = getPhysicalCameraIds(staticMetadata, &physicalIds);
5953 ASSERT_TRUE(Status::OK == rc);
5954 ASSERT_TRUE(physicalIds.size() > 1);
5955
5956 camera_metadata_ro_entry entry;
5957 // Check mainPhysicalId
5958 entry = resultMetadata.find(ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
5959 if (entry.count > 0) {
5960 std::string mainPhysicalId(reinterpret_cast<const char *>(entry.data.u8));
5961 ASSERT_NE(physicalIds.find(mainPhysicalId), physicalIds.end());
5962 } else {
5963 ADD_FAILURE() << "Get LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID failed!";
5964 }
5965 }
5966
5967 // Open a device session with empty callbacks and return static metadata.
openEmptyDeviceSession(const std::string & name,sp<ICameraProvider> provider,sp<ICameraDeviceSession> * session,camera_metadata_t ** staticMeta,::android::sp<ICameraDevice> * cameraDevice)5968 void CameraHidlTest::openEmptyDeviceSession(const std::string &name, sp<ICameraProvider> provider,
5969 sp<ICameraDeviceSession> *session /*out*/, camera_metadata_t **staticMeta /*out*/,
5970 ::android::sp<ICameraDevice> *cameraDevice /*out*/) {
5971 ASSERT_NE(nullptr, session);
5972 ASSERT_NE(nullptr, staticMeta);
5973
5974 ::android::sp<ICameraDevice> device3_x;
5975 ALOGI("configureStreams: Testing camera device %s", name.c_str());
5976 Return<void> ret;
5977 ret = provider->getCameraDeviceInterface_V3_x(
5978 name,
5979 [&](auto status, const auto& device) {
5980 ALOGI("getCameraDeviceInterface_V3_x returns status:%d",
5981 (int)status);
5982 ASSERT_EQ(Status::OK, status);
5983 ASSERT_NE(device, nullptr);
5984 device3_x = device;
5985 });
5986 ASSERT_TRUE(ret.isOk());
5987 if (cameraDevice != nullptr) {
5988 *cameraDevice = device3_x;
5989 }
5990
5991 sp<EmptyDeviceCb> cb = new EmptyDeviceCb();
5992 ret = device3_x->open(cb, [&](auto status, const auto& newSession) {
5993 ALOGI("device::open returns status:%d", (int)status);
5994 ASSERT_EQ(Status::OK, status);
5995 ASSERT_NE(newSession, nullptr);
5996 *session = newSession;
5997 });
5998 ASSERT_TRUE(ret.isOk());
5999
6000 ret = device3_x->getCameraCharacteristics([&] (Status s,
6001 CameraMetadata metadata) {
6002 ASSERT_EQ(Status::OK, s);
6003 *staticMeta = clone_camera_metadata(
6004 reinterpret_cast<const camera_metadata_t*>(metadata.data()));
6005 ASSERT_NE(nullptr, *staticMeta);
6006 });
6007 ASSERT_TRUE(ret.isOk());
6008 }
6009
notifyDeviceState(provider::V2_5::DeviceState newState)6010 void CameraHidlTest::notifyDeviceState(provider::V2_5::DeviceState newState) {
6011 if (mProvider2_5.get() == nullptr) return;
6012
6013 mProvider2_5->notifyDeviceStateChange(
6014 static_cast<hidl_bitfield<provider::V2_5::DeviceState>>(newState));
6015 }
6016
6017 // Open a particular camera device.
openCameraDevice(const std::string & name,sp<ICameraProvider> provider,sp<::android::hardware::camera::device::V1_0::ICameraDevice> * device1)6018 void CameraHidlTest::openCameraDevice(const std::string &name,
6019 sp<ICameraProvider> provider,
6020 sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device1 /*out*/) {
6021 ASSERT_TRUE(nullptr != device1);
6022
6023 Return<void> ret;
6024 ret = provider->getCameraDeviceInterface_V1_x(
6025 name,
6026 [&](auto status, const auto& device) {
6027 ALOGI("getCameraDeviceInterface_V1_x returns status:%d",
6028 (int)status);
6029 ASSERT_EQ(Status::OK, status);
6030 ASSERT_NE(device, nullptr);
6031 *device1 = device;
6032 });
6033 ASSERT_TRUE(ret.isOk());
6034
6035 sp<Camera1DeviceCb> deviceCb = new Camera1DeviceCb(this);
6036 Return<Status> returnStatus = (*device1)->open(deviceCb);
6037 ASSERT_TRUE(returnStatus.isOk());
6038 ASSERT_EQ(Status::OK, returnStatus);
6039 }
6040
6041 // Initialize and configure a preview window.
setupPreviewWindow(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,sp<BufferItemConsumer> * bufferItemConsumer,sp<BufferItemHander> * bufferHandler)6042 void CameraHidlTest::setupPreviewWindow(
6043 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
6044 sp<BufferItemConsumer> *bufferItemConsumer /*out*/,
6045 sp<BufferItemHander> *bufferHandler /*out*/) {
6046 ASSERT_NE(nullptr, device.get());
6047 ASSERT_NE(nullptr, bufferItemConsumer);
6048 ASSERT_NE(nullptr, bufferHandler);
6049
6050 sp<IGraphicBufferProducer> producer;
6051 sp<IGraphicBufferConsumer> consumer;
6052 BufferQueue::createBufferQueue(&producer, &consumer);
6053 *bufferItemConsumer = new BufferItemConsumer(consumer,
6054 GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
6055 ASSERT_NE(nullptr, (*bufferItemConsumer).get());
6056 *bufferHandler = new BufferItemHander(*bufferItemConsumer);
6057 ASSERT_NE(nullptr, (*bufferHandler).get());
6058 (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
6059 sp<Surface> surface = new Surface(producer);
6060 sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
6061
6062 auto rc = device->setPreviewWindow(previewCb);
6063 ASSERT_TRUE(rc.isOk());
6064 ASSERT_EQ(Status::OK, rc);
6065 }
6066
6067 // Stop camera preview and close camera.
stopPreviewAndClose(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6068 void CameraHidlTest::stopPreviewAndClose(
6069 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6070 Return<void> ret = device->stopPreview();
6071 ASSERT_TRUE(ret.isOk());
6072
6073 ret = device->close();
6074 ASSERT_TRUE(ret.isOk());
6075 }
6076
6077 // Enable a specific camera message type.
enableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6078 void CameraHidlTest::enableMsgType(unsigned int msgType,
6079 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6080 Return<void> ret = device->enableMsgType(msgType);
6081 ASSERT_TRUE(ret.isOk());
6082
6083 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
6084 ASSERT_TRUE(returnBoolStatus.isOk());
6085 ASSERT_TRUE(returnBoolStatus);
6086 }
6087
6088 // Disable a specific camera message type.
disableMsgType(unsigned int msgType,const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6089 void CameraHidlTest::disableMsgType(unsigned int msgType,
6090 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6091 Return<void> ret = device->disableMsgType(msgType);
6092 ASSERT_TRUE(ret.isOk());
6093
6094 Return<bool> returnBoolStatus = device->msgTypeEnabled(msgType);
6095 ASSERT_TRUE(returnBoolStatus.isOk());
6096 ASSERT_FALSE(returnBoolStatus);
6097 }
6098
6099 // Wait until a specific frame notification arrives.
waitForFrameLocked(DataCallbackMsg msgFrame,std::unique_lock<std::mutex> & l)6100 void CameraHidlTest::waitForFrameLocked(DataCallbackMsg msgFrame,
6101 std::unique_lock<std::mutex> &l) {
6102 while (msgFrame != mDataMessageTypeReceived) {
6103 auto timeout = std::chrono::system_clock::now() +
6104 std::chrono::seconds(kStreamBufferTimeoutSec);
6105 ASSERT_NE(std::cv_status::timeout,
6106 mResultCondition.wait_until(l, timeout));
6107 }
6108 }
6109
6110 // Start preview on a particular camera device
startPreview(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device)6111 void CameraHidlTest::startPreview(
6112 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device) {
6113 Return<Status> returnStatus = device->startPreview();
6114 ASSERT_TRUE(returnStatus.isOk());
6115 ASSERT_EQ(Status::OK, returnStatus);
6116 }
6117
6118 // Retrieve camera parameters.
getParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,CameraParameters * cameraParams)6119 void CameraHidlTest::getParameters(
6120 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
6121 CameraParameters *cameraParams /*out*/) {
6122 ASSERT_NE(nullptr, cameraParams);
6123
6124 Return<void> ret;
6125 ret = device->getParameters([&] (const ::android::hardware::hidl_string& params) {
6126 ASSERT_FALSE(params.empty());
6127 ::android::String8 paramString(params.c_str());
6128 (*cameraParams).unflatten(paramString);
6129 });
6130 ASSERT_TRUE(ret.isOk());
6131 }
6132
6133 // Set camera parameters.
setParameters(const sp<::android::hardware::camera::device::V1_0::ICameraDevice> & device,const CameraParameters & cameraParams)6134 void CameraHidlTest::setParameters(
6135 const sp<::android::hardware::camera::device::V1_0::ICameraDevice> &device,
6136 const CameraParameters &cameraParams) {
6137 Return<Status> returnStatus = device->setParameters(
6138 cameraParams.flatten().string());
6139 ASSERT_TRUE(returnStatus.isOk());
6140 ASSERT_EQ(Status::OK, returnStatus);
6141 }
6142
allocateGraphicBuffer(uint32_t width,uint32_t height,uint64_t usage,PixelFormat format,hidl_handle * buffer_handle)6143 void CameraHidlTest::allocateGraphicBuffer(uint32_t width, uint32_t height, uint64_t usage,
6144 PixelFormat format, hidl_handle *buffer_handle /*out*/) {
6145 ASSERT_NE(buffer_handle, nullptr);
6146
6147 sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
6148 android::hardware::graphics::allocator::V2_0::IAllocator::getService();
6149 sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocatorV3 =
6150 android::hardware::graphics::allocator::V3_0::IAllocator::getService();
6151
6152 sp<android::hardware::graphics::mapper::V3_0::IMapper> mapperV3 =
6153 android::hardware::graphics::mapper::V3_0::IMapper::getService();
6154 sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
6155 android::hardware::graphics::mapper::V2_0::IMapper::getService();
6156 ::android::hardware::hidl_vec<uint32_t> descriptor;
6157 if (mapperV3 != nullptr && allocatorV3 != nullptr) {
6158 android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
6159 descriptorInfo.width = width;
6160 descriptorInfo.height = height;
6161 descriptorInfo.layerCount = 1;
6162 descriptorInfo.format =
6163 static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
6164 descriptorInfo.usage = usage;
6165
6166 auto ret = mapperV3->createDescriptor(
6167 descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V3_0::Error err,
6168 ::android::hardware::hidl_vec<uint32_t> desc) {
6169 ASSERT_EQ(err, android::hardware::graphics::mapper::V3_0::Error::NONE);
6170 descriptor = desc;
6171 });
6172 ASSERT_TRUE(ret.isOk());
6173
6174 ret = allocatorV3->allocate(descriptor, 1u,
6175 [&](android::hardware::graphics::mapper::V3_0::Error err, uint32_t /*stride*/,
6176 const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
6177 ASSERT_EQ(android::hardware::graphics::mapper::V3_0::Error::NONE, err);
6178 ASSERT_EQ(buffers.size(), 1u);
6179 *buffer_handle = buffers[0];
6180 });
6181 ASSERT_TRUE(ret.isOk());
6182 } else {
6183 ASSERT_NE(mapper.get(), nullptr);
6184 ASSERT_NE(allocator.get(), nullptr);
6185 android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
6186 descriptorInfo.width = width;
6187 descriptorInfo.height = height;
6188 descriptorInfo.layerCount = 1;
6189 descriptorInfo.format = format;
6190 descriptorInfo.usage = usage;
6191
6192 auto ret = mapper->createDescriptor(
6193 descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V2_0::Error err,
6194 ::android::hardware::hidl_vec<uint32_t> desc) {
6195 ASSERT_EQ(err, android::hardware::graphics::mapper::V2_0::Error::NONE);
6196 descriptor = desc;
6197 });
6198 ASSERT_TRUE(ret.isOk());
6199
6200 ret = allocator->allocate(descriptor, 1u,
6201 [&](android::hardware::graphics::mapper::V2_0::Error err, uint32_t /*stride*/,
6202 const ::android::hardware::hidl_vec<::android::hardware::hidl_handle>& buffers) {
6203 ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE, err);
6204 ASSERT_EQ(buffers.size(), 1u);
6205 *buffer_handle = buffers[0];
6206 });
6207 ASSERT_TRUE(ret.isOk());
6208 }
6209 }
6210
verifyRecommendedConfigs(const CameraMetadata & chars)6211 void CameraHidlTest::verifyRecommendedConfigs(const CameraMetadata& chars) {
6212 size_t CONFIG_ENTRY_SIZE = 5;
6213 size_t CONFIG_ENTRY_TYPE_OFFSET = 3;
6214 size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4;
6215 uint32_t maxPublicUsecase =
6216 ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END;
6217 uint32_t vendorUsecaseStart =
6218 ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START;
6219 uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1;
6220 usecaseMask &= ~((1 << maxPublicUsecase) - 1);
6221
6222 const camera_metadata_t* metadata = reinterpret_cast<const camera_metadata_t*> (chars.data());
6223
6224 camera_metadata_ro_entry recommendedConfigsEntry, recommendedDepthConfigsEntry, ioMapEntry;
6225 recommendedConfigsEntry.count = recommendedDepthConfigsEntry.count = ioMapEntry.count = 0;
6226 int retCode = find_camera_metadata_ro_entry(metadata,
6227 ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS, &recommendedConfigsEntry);
6228 int depthRetCode = find_camera_metadata_ro_entry(metadata,
6229 ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS,
6230 &recommendedDepthConfigsEntry);
6231 int ioRetCode = find_camera_metadata_ro_entry(metadata,
6232 ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP, &ioMapEntry);
6233 if ((0 != retCode) && (0 != depthRetCode)) {
6234 //In case both regular and depth recommended configurations are absent,
6235 //I/O should be absent as well.
6236 ASSERT_NE(ioRetCode, 0);
6237 return;
6238 }
6239
6240 camera_metadata_ro_entry availableKeysEntry;
6241 retCode = find_camera_metadata_ro_entry(metadata,
6242 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, &availableKeysEntry);
6243 ASSERT_TRUE((0 == retCode) && (availableKeysEntry.count > 0));
6244 std::vector<int32_t> availableKeys;
6245 availableKeys.reserve(availableKeysEntry.count);
6246 availableKeys.insert(availableKeys.end(), availableKeysEntry.data.i32,
6247 availableKeysEntry.data.i32 + availableKeysEntry.count);
6248
6249 if (recommendedConfigsEntry.count > 0) {
6250 ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
6251 ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS),
6252 availableKeys.end());
6253 ASSERT_EQ((recommendedConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
6254 for (size_t i = 0; i < recommendedConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
6255 int32_t entryType =
6256 recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
6257 uint32_t bitfield =
6258 recommendedConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
6259 ASSERT_TRUE((entryType ==
6260 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
6261 (entryType ==
6262 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
6263 ASSERT_TRUE((bitfield & usecaseMask) == 0);
6264 }
6265 }
6266
6267 if (recommendedDepthConfigsEntry.count > 0) {
6268 ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
6269 ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS),
6270 availableKeys.end());
6271 ASSERT_EQ((recommendedDepthConfigsEntry.count % CONFIG_ENTRY_SIZE), 0);
6272 for (size_t i = 0; i < recommendedDepthConfigsEntry.count; i += CONFIG_ENTRY_SIZE) {
6273 int32_t entryType =
6274 recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_TYPE_OFFSET];
6275 uint32_t bitfield =
6276 recommendedDepthConfigsEntry.data.i32[i + CONFIG_ENTRY_BITFIELD_OFFSET];
6277 ASSERT_TRUE((entryType ==
6278 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) ||
6279 (entryType ==
6280 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT));
6281 ASSERT_TRUE((bitfield & usecaseMask) == 0);
6282 }
6283
6284 if (recommendedConfigsEntry.count == 0) {
6285 //In case regular recommended configurations are absent but suggested depth
6286 //configurations are present, I/O should be absent.
6287 ASSERT_NE(ioRetCode, 0);
6288 }
6289 }
6290
6291 if ((ioRetCode == 0) && (ioMapEntry.count > 0)) {
6292 ASSERT_NE(std::find(availableKeys.begin(), availableKeys.end(),
6293 ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP),
6294 availableKeys.end());
6295 ASSERT_EQ(isZSLModeAvailable(metadata), Status::OK);
6296 }
6297 }
6298
verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,camera_metadata * oldSessionParams,camera_metadata * newSessionParams)6299 void CameraHidlTest::verifySessionReconfigurationQuery(
6300 sp<device::V3_5::ICameraDeviceSession> session3_5, camera_metadata* oldSessionParams,
6301 camera_metadata* newSessionParams) {
6302 ASSERT_NE(nullptr, session3_5.get());
6303 ASSERT_NE(nullptr, oldSessionParams);
6304 ASSERT_NE(nullptr, newSessionParams);
6305
6306 android::hardware::hidl_vec<uint8_t> oldParams, newParams;
6307 oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessionParams),
6308 get_camera_metadata_size(oldSessionParams));
6309 newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessionParams),
6310 get_camera_metadata_size(newSessionParams));
6311 android::hardware::camera::common::V1_0::Status callStatus;
6312 auto hidlCb = [&callStatus] (android::hardware::camera::common::V1_0::Status s,
6313 bool /*requiredFlag*/) {
6314 callStatus = s;
6315 };
6316 auto ret = session3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
6317 ASSERT_TRUE(ret.isOk());
6318 switch (callStatus) {
6319 case android::hardware::camera::common::V1_0::Status::OK:
6320 case android::hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
6321 break;
6322 case android::hardware::camera::common::V1_0::Status::INTERNAL_ERROR:
6323 default:
6324 ADD_FAILURE() << "Query calllback failed";
6325 }
6326 }
6327
main(int argc,char ** argv)6328 int main(int argc, char **argv) {
6329 ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
6330 ::testing::InitGoogleTest(&argc, argv);
6331 CameraHidlEnvironment::Instance()->init(&argc, argv);
6332 int status = RUN_ALL_TESTS();
6333 ALOGI("Test result = %d", status);
6334 return status;
6335 }
6336