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