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