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