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