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